我的代码有点像
trait Checker {
fn check(&self, value: &str) -> bool;
}
struct ShortChecker {}
impl Checker for ShortChecker {
fn check(&self, value: &str) -> bool {
value.len() < 5
}
}
struct PrefixChecker {
prefix: String,
}
impl Checker for PrefixChecker {
fn check(&self, value: &str) -> bool {
value.starts_with(self.prefix)
}
}
fn check(value: &str, which: &str) -> bool {
let checker = if which == "short" {
ShortChecker { }
} else if which == "prefix" {
PrefixChecker { prefix: "xyzzy".to_string() }
} else {
panic!("Unknown option");
};
checker.check(value)
}
Run Code Online (Sandbox Code Playgroud)
这无法编译,因为 if 语句的不同部分返回不同的类型(ShortCheckervs. PrefixChecker)。我所需要的只是有类型的局部变量Checker。我第一次尝试修复它是
let checker: Checker = ...
Run Code Online (Sandbox Code Playgroud)
它发出警告,没有的特征dyn已被弃用。所以我尝试了
let checker: dyn Checker = ...
Run Code Online (Sandbox Code Playgroud)
E0308 失败了,因为
= note: expected trait object `dyn Checker`
found struct `PrefixChecker`
Run Code Online (Sandbox Code Playgroud)
如果我尝试将其存储在结构中以供稍后使用,我知道我需要一个Box<dyn Checker>(或Rc或...)。我是否还需要类似的局部变量?由于变量是本地变量,编译器可以推断它何时会超出范围,因此似乎没有必要包装它。
有没有一种方法可以将对象分配给特征类型的局部变量而不包装它?
您可以使用Box,但您还可以使用另一个巧妙的技巧:
fn check(value: &str, which: &str) -> bool {
let (short_checker, prefix_checker);
let checker: &dyn Checker = if which == "short" {
short_checker = ShortChecker {};
&short_checker
} else if which == "prefix" {
prefix_checker = PrefixChecker {
prefix: "xyzzy".to_string(),
};
&prefix_checker
} else {
panic!("Unknown option");
};
checker.check(value)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
590 次 |
| 最近记录: |