简体   繁体   English

Rust 中的每个泛型是否都必须实现某些特征才能拥有“方法”?

[英]Does every generic in Rust have to implement some trait in order to have 'methods'?

I don't have control over A and B below, they come from a library.我无法控制下面的AB ,它们来自图书馆。 Both implement the hello method, and I'd like to create a function that acts on both, but I don't want to reuse code.两者都实现了hello方法,我想创建一个作用于两者的 function,但我不想重用代码。 On C++, it does not check if a template parameter implements any methods, it just checks if the type in the instantiation implements the method.在 C++ 上,它不检查模板参数是否实现了任何方法,它只是检查实例化中的类型是否实现了该方法。 Take a look:看一看:

pub struct A {
    x: u8,
}

impl A {
    pub fn new() -> A {
        A { x: 0 }
    }
    pub fn hello() {
        println!("hello")
    }
}

pub struct B {
    x: u8,
}

impl B {
    pub fn new() -> B {
        B { x: 1 }
    }
    pub fn hello() {
        println!("hello")
    }
}

pub fn say_hello<T>() {
    let t: T = T::new();
    t.hello();
}

fn main() {
    say_hello::<A>();
    say_hello::<B>();
}

This wont compile because it says T does not have the say_hello method.这不会编译,因为它说T没有say_hello方法。 Since this is from a library, I cannot implement a trait for them.由于这是来自图书馆,我无法为他们实现特征。 So there's nothing I can do here?所以我在这里无能为力吗? I'll have to duplicate code?我将不得不复制代码?

Note that it can be known at compile time if both the intantiation types A and B have the hello method.请注意,如果实例化类型AB都具有hello方法,则可以在编译时知道。 C++ wouldn't care. C++ 不在乎。

TLDR: yes. TLDR:是的。

C++'s templates are indeed differ from generic types (particularly in Rust). C++ 的模板确实不同于泛型类型(尤其是在 Rust 中)。 The first one works by substitution without digging into the type at time of item definition, but only at time of use .第一个通过替换而不在项目定义时深入研究类型,但仅在使用时 So in C++, I believe, it is possible to create a templated item that at the same time compiles and cannot have an instantiation because of conflicting requirements.因此,我相信在 C++ 中,可以创建一个模板项,该项同时编译并且由于需求冲突而无法实例化。

This is not the case for generic types in Rust, these are checked while you define a generic item, eg T in fn f<T>(..) {..} . Rust 中的泛型类型不是这种情况,在定义泛型项时会检查这些类型,例如 fn f< T fn f<T>(..) {..}中的 T。 So the compiler analyzes all of the usages of the type T and its instances so these are used properly.因此编译器分析了类型T及其实例的所有用法,以便正确使用它们。

So in general yes, you need to have a trait bound to use types' methods.所以一般来说是的,你需要有一个特征绑定到使用类型的方法。 As for your case this might be a preferred solution:至于您的情况,这可能是首选解决方案:

trait Hello {
    fn say_hello();
}

impl Hello for A {
    fn say_hello() {
        A::hello()
    }
}

impl Hello for B {
    fn say_hello() {
        B::hello()
    }
}

If you'd like to have a behavior similar to templates in C++ you may take a look at macros :如果您希望在 C++ 中具有类似于模板的行为,您可以查看

macro_rules! say_hello {
    ($t:ty) => {{
        <$t>::hello()
    }}
}

fn main() {
    say_hello!(A);
    say_hello!(B);
}

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

相关问题 Rust是否具有所有实体“继承”或实现的类型或特征? - Does Rust have a type or trait that all entities “inherit” or implement? 为什么在泛型函数中对特征的引用必须实现`Sized`? - Why does a reference to a trait in a generic function have to implement `Sized`? 我是否必须“使用”特征才能调用该特征中定义的方法? - Do I have to 'use' a trait in order to call methods defined in that trait? Rust 标准库是否具有最小/最大特征? - Does the Rust standard library have a Min/Max trait? 是否可以在 Rust 中实现泛型类型的特征? - Is it possible to implement a trait for a generic type in Rust? 无法在 rust 柴油机中使用通用参数实现特征 - Cannot implement trait with generic param in rust diesel 是否可以在特征上具有通用功能? - Is it possible to have a generic function on a trait? 当我们只有一个通用特征时,处理常量数学的 Rust 方法是什么 - What is the Rust way to deal with constant math when we only have a generic trait 为了向下转换一个特征对象,为什么它必须是静态的? - In order to downcast a trait object why does it have to be static? 一个结构是否可以引用具有泛型方法的trait对象,而不使该结构本身具有泛型? - Is it possible for a struct to have a reference to a trait object that has generic methods, without making the struct itself generic?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM