我正在尝试创建一个特征对象的向量,但我得到了类型不匹配。我还尝试使用. map()
代替for循环,但遇到了同样的问题。这是我真实代码的最小版本,我意识到这个例子不需要使用特征对象,但我的真实代码需要,因为列表中除了Link
之外还有其他类型,它们也实现了Speak
。如何使用正确的类型创建Vec
以便将其传递给trait_objects
?
use std::fs;
fn main() {
// let links = fs::read_dir("my_dir").unwrap();
// let links: Vec<Box<dyn Speak>> = links
// .map(|file| {
// let myfile = file.unwrap();
// let href = myfile.path().to_str().unwrap();
// Box::new(Link { attr: href })
// })
// .collect();
let links = Vec::new();
for entry in fs::read_dir("my_dir").unwrap() {
let myfile = entry.unwrap();
let href = myfile.path().to_str().unwrap();
links.push(Box::new(Link { attr: href }));
}
let link_objects = ListOfTraitObjects {
trait_objects: links,
};
for link in link_objects.trait_objects.iter() {
println!("{}", link.speak());
}
}
trait Speak {
fn speak(&self) -> String;
}
struct ListOfTraitObjects {
trait_objects: Vec<Box<dyn Speak>>,
}
struct Link<'a> {
attr: &'a str,
}
impl Speak for Link<'_> {
fn speak(&self) -> String {
self.attr.to_string()
}
}
您的代码存在几个问题。首先,您正在创建一个 Vec
links.push(Box::new(Link { attr: href }) as Box::<dyn Speak>);
游乐场
然而,这会产生两个新的错误:
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:7:20
|
7 | let href = myfile.path().to_str().unwrap();
| ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary which is freed while still in use
8 | links.push(Box::new(Link { attr: href }) as Box::<dyn Speak>);
| ----------------------------- cast requires that borrow lasts for `'static`
error[E0596]: cannot borrow `links` as mutable, as it is not declared as mutable
--> src/lib.rs:8:9
|
4 | let links = Vec::new();
| ----- help: consider changing this to be mutable: `mut links`
...
8 | links.push(Box::new(Link { attr: href }) as Box::<dyn Speak>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
第一个错误是因为
Link
结构从条目
中借用了一个字符串,但条目
只在当前循环迭代时存在。即使错误指出强制转换需要“静态
生存期”,如果您只是尝试构建Vec,也会收到类似的错误
struct Link {
attr: String,
}
impl Speak for Link {
fn speak(&self) -> String {
self.attr.clone()
}
}
第二个错误更容易,只需按照编译器的建议将
let links = ...
替换为 let mut links = ...
即可修复。
完整工作示例:
use std::fs;
fn main() {
let mut links = Vec::new();
for entry in fs::read_dir("my_dir").unwrap() {
let myfile = entry.unwrap();
let href = myfile.path().to_str().unwrap().to_string();
links.push(Box::new(Link { attr: href }) as Box::<dyn Speak>);
}
let link_objects = ListOfTraitObjects {
trait_objects: links,
};
for link in link_objects.trait_objects.iter() {
println!("{}", link.speak());
}
}
trait Speak {
fn speak(&self) -> String;
}
struct ListOfTraitObjects {
trait_objects: Vec<Box<dyn Speak>>,
}
struct Link {
attr: String,
}
impl Speak for Link {
fn speak(&self) -> String {
self.attr.clone()
}
}
游乐场
同样的修复也可以应用于基于迭代器的解决方案:
let links = fs::read_dir("my_dir").unwrap();
let links: Vec<_> = links
.map(|file| {
let myfile = file.unwrap();
let href = myfile.path().to_str().unwrap().to_string();
Box::new(Link { attr: href }) as Box<dyn Speak>
})
.collect();
游乐场
(这是我第二次尝试追踪我的确切问题。查看编辑历史记录) 我有一个简单的通用特性和两种不同的实现: 我现在想要一个包含两个实现元素的向量。正如我在这里学到的,我做: 但是编译器不同意: 一方面,这是有道理的。另一方面,我应该为写什么?我希望它是通用的,所以我不能简单地在那里放或。我可以做
考虑以下代码: 当我尝试推送<code>cat</code>时,编译器告诉我<code>v</code>是<code>动物</code>的向量(类型不匹配) 那么,如何制作一个属于trait的对象向量,并在每个元素上调用相应的trait方法呢?
本文向大家介绍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