到目前为止,在我的项目中,我使用许多特性来允许在注入依赖项的单元测试中进行模拟/存根.然而,到目前为止我所做的一个细节似乎很可疑,我甚至惊讶它甚至编译.我担心会发生一些我看不见或不明白的危险事件.它基于这两种方法签名之间的差异:
fn confirm<T>(subject: &MyTrait<T>) ...
fn confirm<T>(subject: impl MyTrait<T>) ...
Run Code Online (Sandbox Code Playgroud)
我只是impl ...在方法参数中发现了语法,它似乎是唯一记录的方法,但是我的测试已经使用了另一种方式,我根据Go解决了同样的问题(方法的大小)来直觉编译时的参数,当参数可以是接口的任何实现者,并且引用可以来拯救).
这两者有什么区别?为什么他们都被允许?它们都代表合法用例,还是我的参考语法(&MyTrait<T>)严格来说更糟糕?
我需要一个获取实现trait Option的泛型类型的函数。一个幼稚的实现可能看起来像以下内容(是的,解包可能会引起恐慌):Tstd::iter::IntoIteratorNone
fn main() {
let v = vec![1i32, 2, 3];
print_iter(Some(v));
print_iter(None);
}
fn print_iter<T: IntoIterator<Item = i32>>(v: Option<T>) {
for e in v.unwrap() {
println!("{}", e);
}
}
Run Code Online (Sandbox Code Playgroud)
在操场上测试。
这可以按预期工作Some(...),但因以下原因而失败None:
error[E0282]: type annotations needed
--> src/main.rs:4:5
|
4 | print_iter(None);
| ^^^^^^^^^^ cannot infer type for `T`
Run Code Online (Sandbox Code Playgroud)
T在这些情况下,显然类型是未知的。一个人可以使用,print_iter::<Vec<i32>>(None);但这并不是真正的习惯,因为这提供了一些不基于任何东西的任意类型...
有什么方法可以向编译器暗示我不在乎None或使用某种默认值吗?