在 rust-lang 中, `static_fly::(number);` 和 `static_fly(number);` 有什么区别

发布于 2025-01-15 07:09:40 字数 726 浏览 3 评论 0原文

在 rust-lang 中, static_fly::(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
}

这有什么区别两个电话。

in rust-lang, what's the difference between static_fly::<Number>(number); and static_fly(number);

here is a demo:

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
}

what's the difference between this two calling.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

恏ㄋ傷疤忘ㄋ疼 2025-01-22 07:09:40

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

如果有足够的信息,Rust 可以推断泛型类型参数。对于 static_fly(number) ,编译器推断 TNumber。对于 static_fly::(number) ,您只需显式提供类型参数 T 的类型。

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

let number = Zero;
let number: Number = Zero;

原理相同——在一种情况下我们指定类型,在另一种情况下我们让编译器计算出来。

The two methods of calling the function are equivalent in this case.

Given enough information, Rust can infer generic type arguments. In the case of static_fly(number) the compiler has inferred that T is Number. In the case of static_fly::<Number>(number) you are just providing the type for the type argument T explicitly.

This is very similar to other kinds of inference the compiler performs. For example, both of these statements are also equivalent:

let number = Zero;
let number: Number = Zero;

It's the same principle -- in one case we specify the type, in the other we let the compiler figure it out.

横笛休吹塞上声 2025-01-22 07:09:40

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<_>>();

Its the same thing as let a = b; compared to let a: Type = b;. It gives you the option to explicitly state which type is used in an operation. Normally Rust can infer what you want to do, however if there is any ambiguity the compiler will ask you to explicitly specify a type.

For example, the most common instance of this I run into is when calling .collect() on an iterator.


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]
}

For this example there are a couple ways you can fix 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>>();

Another option is to only partially state the type in question. A type name can be replaced with an underscore to tell the compiler to infer that part of a type. This is generally my preferred way of handling this specific case.

// 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<_>>();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文