首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在铁锈-朗中,`static_fly::<Number>(数字);‘和`static_fly(数字);’

在铁锈-朗中,`static_fly::<Number>(数字);‘和`static_fly(数字);’
EN

Stack Overflow用户
提问于 2022-03-19 13:37:50
回答 2查看 68关注 0票数 0

在铁锈-朗,static_fly::<Number>(number);static_fly(number);有什么区别?

下面是一个演示:

代码语言:javascript
复制
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
}

这两个电话有什么区别。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-03-19 14:02:21

在这种情况下,调用函数的两种方法是等价的。

给定足够的信息,Rust可以推断出泛型类型参数。在static_fly(number)的例子中,编译器推断TNumber。在static_fly::<Number>(number)的情况下,您只是显式地为类型参数T提供类型。

这与编译器执行的其他类型的推断非常相似。例如,这两种语句也是等价的:

代码语言:javascript
复制
let number = Zero;
let number: Number = Zero;

这是相同的原则--在一种情况下,我们指定类型,在另一种情况下,我们让编译器计算出来。

票数 1
EN

Stack Overflow用户

发布于 2022-03-19 14:10:34

它和let a = b;let a: Type = b;是一样的。它为您提供了显式声明在操作中使用哪种类型的选项。通常,Rust可以推断出您想要做什么,但是如果编译器会要求您显式地指定一个类型,那么如果有任何不明确之处的话。

例如,我遇到的最常见的实例是在迭代器上调用.collect()时。

代码语言:javascript
复制
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

代码语言:javascript
复制
// 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>>();

另一种选择是只部分说明所讨论的类型。可以用下划线替换类型名称,让编译器推断类型的这一部分。这通常是我喜欢的处理这一具体案件的方式。

代码语言:javascript
复制
// 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<_>>();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71538603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档