我可以在 Rust 中定义自己的"strong"类型别名吗?



tl;dr在Rust中是否有一个" strong ";类型别名(或输入机制),这样rustc编译器将拒绝(发出一个错误)搞混,可能是相同的底层类型?

问题当前,可以定义相同底层类型的类型别名

type WidgetCounter = usize;
type FoobarTally = usize;

然而,如果我错误地混淆了两个类型别名的实例,编译器将不会拒绝(发出错误或警告)。

fn tally_the_foos(tally: FoobarTally) -> FoobarTally {
// ...
tally
}
fn main() {
let wc: WidgetCounter = 33;
let ft: FoobarTally = 1;
// whoops, passed the wrong variable!
let tally_total = tally_the_foos(wc);
}

(锈操场)

可能的解决方案?

我希望有一个额外的关键字strong

strong type WidgetCounter = usize;
strong type FoobarTally = usize;

使得前面的代码在编译时会导致编译错误:

error[E4444]: mismatched strong alias type WidgetCounter,
expected a FoobarTally

或者可能有一个聪明的技巧与structs可以实现这一点?

还是定义宏来完成此操作的装载模块?



我知道我可以"破解";这是通过类型混叠不同的数字类型,即i32,然后u32,然后i64,等等。但是,由于许多原因,这是一个丑陋的hack。


是否有一种方法可以让编译器帮助我避免这些自定义类型别名混淆?

Rust有一个很好的技巧,叫做New Type Idiom。通过在元组结构中包装单个项,可以创建一个"强"结构。或";distinct"包装类型。

在Rust文档的元组结构部分也简要地提到了这个习语。

New Type Idiom"林克有一个很好的例子。这里有一个类似于您正在寻找的类型:

// Defines two distinct types. Counter and Tally are incompatible with
// each other, even though they contain the same item type.
struct Counter(usize);
struct Tally(usize);
// You can destructure the parameter here to easily get the contained value.
fn print_tally(Tally(value): &Tally) {
println!("Tally is {}", value);
}
fn return_tally(tally: Tally) -> Tally {
tally
}
fn print_value(value: usize) {
println!("Value is {}", value);
}
fn main() {
let count: Counter = Counter(12);
let mut tally: Tally = Tally(10);
print_tally(&tally);
tally = return_tally(tally);
// This is a compile time error.
// Counter is not compatible with type Tally.
// print_tally(&count);
// The contained value can be obtained through destructuring
// or by potision.
let Tally(tally_value ) = tally;
let tally_value_from_position: usize = tally.0;
print_value(tally_value);
print_value(tally_value_from_position);
}

相关内容

  • 没有找到相关文章