I have been trying to understand if it is possible to provide literals as function parameter types.
This is something I do quite frequently with Typescript and was wondering if there is a way to do this in rust. e.g.
function example(param: 1 | 2) { }
example(1); // OK
example(2); // OK
example(3); // Type Error
or better yet.
const FLAGS = {
a: 1,
b: 2,
} as const;
export type ValueOf<T> = T[keyof T];
function example(flag: ValueOf<typeof FLAGS>) {}
example(FLAGS.a); // OK
example(1); // OK
example(FLAGS.b); // OK
example(2); // OK
example(3); // Type Error
CodePudding user response:
This can be accomplished using enums as stated in @David Fong's comment.
example from rust book.
enum Coin {
Penny,
Nickel,
Dime,
Quarter,
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter => 25,
}
}
CodePudding user response:
I agree with everything that all the others here have said, so I won't provide another solution. I wanted to give some background information.
It's important here to distinguish between information that is known at compile time and information that is known at runtime.
- Types are known at compile time, so the compiler can complain about them if they are incorrect.
- Values, meaning the content of a variable, are only known at runtime. Therefore it's impossible for the compiler to check for them. You will never be able to restrict a parameter to values between 10 and 20 at compile time, because that's simply information the compiler does not have.
It's a little different in Javascript, because the borders between compile time and runtime are a little muddy, as it's an interpreted language. But in Rust, there is a hard cut.
That said, as others already pointed out, most problems can be expressed through enums, which are types and therefore known at compile time.