简体   繁体   English

从泛型类型的特征调用静态方法

[英]Call static method from trait on generic type

I have a trait with one function that does not take self as an argument:我有一个不以self作为参数的函数的特征:

trait MyTrait {
    fn function(x: i32) -> i32;
}

struct Dummy;

impl MyTrait for Dummy {
    fn function(x: i32) -> i32 {
        x * 2
    }
}

fn call_method<T: MyTrait>(object: T) {
    let x = object.function(2);
}

fn main() {}

The user of the library is required to implement the trait for any type, usually an empty struct.库的用户需要为任何类型实现 trait,通常是一个空结构。 One of my functions accepts a generic type that implements MyTrait .我的一个函数接受一个实现MyTrait的泛型类型。 When I try to call the function method on the generic type, it gives me this error:当我尝试在泛型类型上调用function方法时,它给了我这个错误:

error: no method named function found for type T in the current scope错误:在当前范围内找不到类型T名为function方法

I tried the solution in the answer to this question , but I get the same error.我在这个问题的答案中尝试了解决方案,但我得到了同样的错误。 How can I call a static method on a generic type?如何在泛型类型上调用静态方法?

When I try to call the function method on the generic type, ...当我尝试在泛型类型上调用function方法时,...

Two things: first of all, depending on how you want to look at it, function isn't a method.两件事:首先,取决于您想如何看待它, function不是方法。 It's just a function that happens to live in the trait's namespace ( aka an "associated function").它只是一个碰巧存在于特征命名空间中的函数(又名“关联函数”)。

Secondly, you're not trying to call function on the type, you're calling it on a value of that type.其次,您不是试图在类型上调用function ,而是在该类型的值上调用它。 This is impossible because, again, it's not a method;这是不可能的,因为它又不是一种方法; it doesn't have a self parameter.它没有self参数。

The solution is to actually call the function associated function on the generic type, which looks like this:解决方法是在泛型类型上实际调用function关联函数,如下所示:

fn call_method<T: MyTrait>(object: T) {
    let x = T::function(2);
}

Sometimes, this won't be specific enough.有时,这不够具体。 If you need to be more specific, you can also write the above as:如果你需要更具体,你也可以把上面的写成:

fn call_method<T: MyTrait>(object: T) {
    let x = <T as MyTrait>::function(2);
}

The two are semantically identical ;两者在语义上是相同的 it's just that the second is more specific and more likely to resolve when you have lots of traits involved.只是当您涉及很多特征时,第二个更具体并且更有可能解决。

Following on DK.关注DK。 answer, you don't actually need to pass "object: T" as an argument to your function.回答,您实际上并不需要将“对象:T”作为参数传递给您的函数。

You can just do你可以做

fn call_method<T: MyTrait>() {
    let x = T::function(2);
}

In fact, if I got it right, you are not passing this struct to the function but merely linking it through the T, so there is no move/borrow semantics involved.事实上,如果我猜对了,您不会将此结构传递给函数,而只是通过 T 链接它,因此不涉及移动/借用语义。 But I might be wrong here .但我在这里可能是错的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM