[英]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.我无法控制下面的A
和B
,它们来自图书馆。 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.请注意,如果实例化类型A
和B
都具有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.