考虑以下代码:
trait Animal {
fn make_sound(&self) -> String;
}
struct Cat;
impl Animal for Cat {
fn make_sound(&self) -> String {
"meow".to_string()
}
}
struct Dog;
impl Animal for Dog {
fn make_sound(&self) -> String {
"woof".to_string()
}
}
fn main () {
let dog: Dog = Dog;
let cat: Cat = Cat;
let v: Vec<Animal> = Vec::new();
v.push(cat);
v.push(dog);
for animal in v.iter() {
println!("{}", animal.make_sound());
}
}
当我尝试推送<code>cat</code>时,编译器告诉我<code>v</code>是<code>动物</code>的向量(类型不匹配)
那么,如何制作一个属于trait的对象向量,并在每个元素上调用相应的trait方法呢?
您可以使用引用特征对象
通过添加
Vec
来更改的泛型类型
fn main() {
let dog: Dog = Dog;
let cat: Cat = Cat;
let mut v: Vec<&Animal> = Vec::new();
// ~~~~~~~
v.push(&dog);
v.push(&cat);
for animal in v.iter() {
println!("{}", animal.make_sound());
}
// Ownership is still bound to the original variable.
println!("{}", cat.make_sound());
}
如果您想保留原始变量的所有权并在以后重用它,这是非常好的。
请记住上面的场景,您不能转让
dog
或cat
的所有权,因为Vec
在同一范围内借用了这些具体实例。
引入新作用域有助于处理该特定情况:
fn main() {
let dog: Dog = Dog;
let cat: Cat = Cat;
{
let mut v: Vec<&Animal> = Vec::new();
v.push(&dog);
v.push(&cat);
for animal in v.iter() {
println!("{}", animal.make_sound());
}
}
let pete_dog: Dog = dog;
println!("{}", pete_dog.make_sound());
}
<代码>Vec
<anon>:22:9: 22:40 error: instantiating a type parameter with an incompatible type `Animal`, which does not fulfill `Sized` [E0144]
<anon>:22 let mut v: Vec<Animal> = Vec::new();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这不合法的原因是Vec
为了解决这个问题,我们需要在
Vec
中存储具有大小的东西。最直接的解决方案是将值包装在Box
中,即Vec
下面是一个工作的< code>main
:
fn main() {
let dog: Dog = Dog;
let cat: Cat = Cat;
let mut v: Vec<Box<Animal>> = Vec::new();
v.push(Box::new(cat));
v.push(Box::new(dog));
for animal in v.iter() {
println!("{}", animal.make_sound());
}
}
(这是我第二次尝试追踪我的确切问题。查看编辑历史记录) 我有一个简单的通用特性和两种不同的实现: 我现在想要一个包含两个实现元素的向量。正如我在这里学到的,我做: 但是编译器不同意: 一方面,这是有道理的。另一方面,我应该为写什么?我希望它是通用的,所以我不能简单地在那里放或。我可以做
我正在尝试创建一个特征对象的向量,但我得到了类型不匹配。我还尝试使用代替for循环,但遇到了同样的问题。这是我真实代码的最小版本,我意识到这个例子不需要使用特征对象,但我的真实代码需要,因为列表中除了之外还有其他类型,它们也实现了。如何使用正确的类型创建以便将其传递给?
本文向大家介绍Java面向对象的三大特征,包括了Java面向对象的三大特征的使用技巧和注意事项,需要的朋友参考一下 java面向对象的三大特征:“封装、继承、多态”。更多Java技术知识,请登陆疯狂软件教育官网。微信搜索微信号:疯狂软件,参加2015年优惠活动,有机会获得优惠劵和代金劵。 以本文为例,User类中的变量为私有变量,只能通过创建对象(此时构造方法自动调用)来赋值。 外界只
关于一个语言被称为面向对象所需的功能,在编程社区内并未达成一致意见。Rust 被很多不同的编程范式影响,包括面向对象编程;比如第十三章提到了来自函数式编程的特性。面向对象编程语言所共享的一些特性往往是对象、封装和继承。让我们看一下这每一个概念的含义以及 Rust 是否支持他们。In my view the Gang of Four is the best book ever written on
特征值
trait对象在Rust中是指使用指针封装了的 trait,比如 &SomeTrait 和 Box<SomeTrait>。 trait Foo { fn method(&self) -> String; } impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } } impl Foo for String