我正在寻找一种将类型约束转移到某种包装器中的方法。例如,在 Ada 中您可能会看到如下内容:
type Element is Integer range 100 .. 1000;
Run Code Online (Sandbox Code Playgroud)
它定义了一种新类型Element,尽管它仍然是整数,但它绑定到特定范围。还有mod一个会循环回来(超级有用)。
在 Rust 中,到目前为止,我一直在我的所有函数中手动检查这一点,即:
if x < 100 || x >= 1000 {
// throw some kind of error
}
Run Code Online (Sandbox Code Playgroud)
但最好定义一个新类型,在赋值时为我执行此检查,类似于默认情况下整数不能溢出的方式。我知道我们没有继承,但也许我可以实现某种特征?
TL;DR:我确信我的方法不是最佳实践,但是标准的替代方法是什么?
在 Rust 中,您可以为任何实现其他特征组合的类型自动实现特征。IE:
impl<T: Foo + Bar> SomeTrait for T {
some_function(&self) {
/*...*/
}
}
Run Code Online (Sandbox Code Playgroud)
我想做的是定义一种关系,其中和 都Foo足以Bar自行实现。基本上是这样的:SomeTrait
impl<T: Foo> SomeTrait for T {
some_function(&self) {
/*...*/
}
}
impl<T: Bar> SomeTrait for T {
some_function(&self) {
/*...*/
}
}
Run Code Online (Sandbox Code Playgroud)
这不会编译,因为您要实现SomeTrait两次T,并且编译器不可能知道在 where 的情况下要做什么T: Foo + Bar,但能够做到这一点真是太好了。
有没有某种方法可以“抽象”解决这个问题,以便我可以调用some_function()实现TOR 的Foo方法Bar?或者我是否只能选择一种实现?
我正在尝试创建一个crash!基本上只是包装的自定义宏eprintln!,但它可以是任何其他format!类似的宏。目前看起来是这样的。
macro_rules! crash {
($fmt_str:literal, $($args:expr),*) => {{
eprintln!($fmt_str, $args);
std::process::exit(1);
}};
}
Run Code Online (Sandbox Code Playgroud)
我无法$args直接使用,因为它仍在重复,所以我需要某种方法将其分开,但我不知道该怎么做。