英文:
Getting a slice of trait objects from a slice of an associated type
问题
我有两个相关的特性 `List` 和 `ListItem` ([playground 链接][1])。
```rust
trait List {
type Item: ListItem;
fn items(&self) -> Vec<Self::Item>;
/* 更多内容 */
}
其中 Item
是 List
上的关联类型,而 ListItem
对于 PartialEq
和 Debug
有自定义实现。
在一个看起来像这样的 List
特性方法内:
fn foo(&self, other: &dyn List<Item=Self::Item>)
我想要比较项目的子切片,使用为 ListItem
定义的 PartialEq
。
例如:
let lhs: &[&dyn ListItem] = ...;
let rhs: &[&dyn ListItem] = ...;
assert_eq!(lhs, rhs);
但我无法将切片强制转换为正确的类型。
fn foo(&self, other: &dyn List<Item = Self::Item>) {
let items = self.items();
let items_slice: &[&dyn ListItem] = items.as_slice(); // <-- 这里有错误
error[E0308]: 不匹配的类型
|
40 | let these: &[&dyn ListItem] = these_items.as_slice();
| ---------------- ^^^^^^^^^^^^^^^^^^^^^^ 期望类型为 `&[&dyn ListItem]`,找到类型为 `&[<Self as List>::Item]`
| |
| 期望类型
|
= 注意:期望引用 `&[&dyn ListItem]`
找到引用 `&[<Self as List>::Item]`
= 帮助:考虑将关联类型 `<Self as List>::Item` 约束为 `&dyn ListItem`
= 注意:更多信息请访问 https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
我该如何强制转换切片为正确的类型?
<details>
<summary>英文:</summary>
I have two related traits `List` and `ListItem` ([playground link][1]).
```rust
trait List {
type Item: ListItem;
fn items(&self) -> Vec<Self::Item>;
/* more stuff */
}
where Item
is an associated type on List
and ListItem
has a custom implementation for PartialEq
and Debug
Inside of a List
trait method that looks like
fn foo(&self, other: &dyn List<Item=Self::Item>)
I would like to compare sub-slices of the items, using the PartialEq
defined for ListItem
.
e.g.
let lhs: &[&dyn ListItem] = ...;
let rhs: &[&dyn ListItem] = ...;
assert_eq!(lhs, rhs);
but I cannot coerce the slices to the correct type.
fn foo(&self, other: &dyn List<Item = Self::Item>) {
let items = self.items();
let items_slice: &[&dyn ListItem] = items.as_slice(); // <-- Error here
error[E0308]: mismatched types
|
40 | let these: &[&dyn ListItem] = these_items.as_slice();
| ---------------- ^^^^^^^^^^^^^^^^^^^^^^ expected `&[&dyn ListItem]`, found `&[<Self as List>::Item]`
| |
| expected due to this
|
= note: expected reference `&[&dyn ListItem]`
found reference `&[<Self as List>::Item]`
= help: consider constraining the associated type `<Self as List>::Item` to `&dyn ListItem`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
How can I coerce the slice to the correct type?
答案1
得分: 1
你不能。首先,你需要引用,而 items
包含拥有的项目。其次,你需要胖指针,而 items
具有具体的类型。
你需要将它们收集到一个 Vec
中:
let items = self.items();
let items_dyn = items
.iter()
.map(|item| item as &dyn ListItem)
.collect::<Vec<_>>();
英文:
You cannot. First, you need references, and items
contains owned items. Second, you need fat references, and items
has concrete types.
You need to collect them into a Vec
:
let items = self.items();
let items_dyn = items
.iter()
.map(|item| item as &dyn ListItem)
.collect::<Vec<_>>();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论