在铁锈-朗,static_fly::<Number>(number);和static_fly(number);有什么区别?
下面是一个演示:
enum Number {
Zero,
One,
Two,
}
trait Fly {
fn fly(&self);
}
impl Fly for Number {
fn fly(&self) {
println!("flying number: {}", self)
}
}
// 静态分发
fn static_fly<T: Fly>(f: T){
print!("静态分发\t");
f.fly()
}
fn main() {
let number = Zero;
// 泛型的分发调用
static_fly(number); // <-- here is the 1st method for calling static_fly
// static_fly::<Number>(number); // <-- here is the 2nd method for calling static_fly
}这两个电话有什么区别。
发布于 2022-03-19 14:02:21
在这种情况下,调用函数的两种方法是等价的。
给定足够的信息,Rust可以推断出泛型类型参数。在static_fly(number)的例子中,编译器推断T是Number。在static_fly::<Number>(number)的情况下,您只是显式地为类型参数T提供类型。
这与编译器执行的其他类型的推断非常相似。例如,这两种语句也是等价的:
let number = Zero;
let number: Number = Zero;这是相同的原则--在一种情况下,我们指定类型,在另一种情况下,我们让编译器计算出来。
发布于 2022-03-19 14:10:34
它和let a = b;和let a: Type = b;是一样的。它为您提供了显式声明在操作中使用哪种类型的选项。通常,Rust可以推断出您想要做什么,但是如果编译器会要求您显式地指定一个类型,那么如果有任何不明确之处的话。
例如,我遇到的最常见的实例是在迭代器上调用.collect()时。
fn foo(vals: &[u32]) -> Vec<u32> {
// In this case there is no ambiguity since the result of collect must
// be a `Vec<u32>`. Since the compiler can infer the type, we don't need
// to state what type collect uses.
vals.iter()
.map(|x| x * 2)
.collect()
}
fn bar(vals: &[u32]) -> u32 {
// In this case the compiler is unable to infer a type as collect can
// create any type that can be initialized with an iterator.
let mut a = vals.iter()
.map(|x| x * 2)
.collect();
a.sort();
a[0]
}对于这个例子,有几种方法可以修复bar。
// State the type of a so the compiler can infer collect's types
let mut a: Vec<u32> = vals.iter()
.map(|x| x * 2)
.collect();
// State the types used by the function in question but let the compiler infer a's type
let mut a = vals.iter()
.map(|x| x * 2)
.collect::<Vec<u32>>();另一种选择是只部分说明所讨论的类型。可以用下划线替换类型名称,让编译器推断类型的这一部分。这通常是我喜欢的处理这一具体案件的方式。
// Tell the compiler we will collect items to a Vec, but let it infer the content type
let mut a = vals.iter()
.map(|x| x * 2)
.collect::<Vec<_>>();https://stackoverflow.com/questions/71538603
复制相似问题