从迭代器返回的关联类型中提取结构
Pull struct out of associated type returned by iterator
我正在用 Rust 实现双链表。我创建了一个运行良好的迭代器。
#[derive(Clone, Debug)]
pub struct LLCursor<T: Copy> {
pub cur: Option<Rc<RefCell<Node<T>>>>,
}
impl<T> IntoIterator for List<T>
where
T: Clone + Copy,
{
type Item = Rc<RefCell<Node<T>>>;
type IntoIter = LLCursor<T>;
fn into_iter(self) -> Self::IntoIter {
LLCursor {
cur: self.head.clone(),
}
}
}
impl<T> Iterator for LLCursor<T>
where
T: Copy,
{
type Item = Rc<RefCell<Node<T>>>;
fn next(&mut self) -> Option<Rc<RefCell<Node<T>>>> {
match self.cur.clone() {
Some(node) => {
self.cur = node.borrow().next.clone();
Some(node)
}
None => None,
}
}
}
我想创建一个函数,可以在迭代时访问链表节点的内容。像这样:
pub fn print(self)
where
List<T>: IntoIterator,
<List<T> as IntoIterator>::Item: std::fmt::Debug,
{
for i in self {
println!("{:?}", Some(i.borrow().clone().item));
}
}
错误:
error[E0599]: no method named `borrow` found for associated type `<List<T> as IntoIterator>::Item` in the current scope
--> src/list.rs:90:51
|
90 | println!("{:?}", i.borrow().clone().item);
| ^^^^^^ method not found in `<List<T> as IntoIterator>::Item`
|
= help: items from traits can only be used if the trait is in scope
= note: the following trait is implemented but not in scope; perhaps add a `use` for it:
`use std::borrow::Borrow;`
我了解 i
在这种情况下属于 <List<T> as IntoIterator>::Item
类型。我是生锈的新手,所以我看不出迭代器 returns 以这种方式关联的类型有何用处。我希望 i
是 Option<Rc<RefCell<Node<T>>>>
类型。有没有一种方法可以将其从关联类型中提取出来,以便我能够访问每个单独节点的元素?
None 的迭代器代码实际上需要 T: Copy
,我建议你删除它,因为它混淆了你的问题。那么,既然知道<List<T> as IntoIterator>::Item
其实就是T
,那么就可以直接使用了:
pub fn print(self) where T: Debug {
for i in self {
println!("{:?}", i.borrow().item);
}
}
我还在打印时删除了 .clone()
,因为它是不必要的,并且避免了 T: Clone
约束。看到它在 playground.
上工作
你得到错误的原因是因为约束 List<T>: IntoIterator
和 Item: Debug
并不意味着 Item
是 Rc<RefCell<_>>
。您需要一个额外的约束 T: Copy
才能推断出正确的 IntoIterator
实现。就您演示的代码而言,不存在其他实现,但理论上存在不冲突的实现可能,并且编译器不会进行猜测。
作为旁注,对 Self
类型(此处明确表示为 List<T>
)的约束非常少见,除非在特征中,因为您通常知道 Self
需要什么来满足这些限制,并且直接列出它更具描述性。 (即,如果 Self
需要 Clone
,但您知道 Self
是 Clone
如果 T
是 Clone
,您将使用 T: Clone
作为约束)。
我正在用 Rust 实现双链表。我创建了一个运行良好的迭代器。
#[derive(Clone, Debug)]
pub struct LLCursor<T: Copy> {
pub cur: Option<Rc<RefCell<Node<T>>>>,
}
impl<T> IntoIterator for List<T>
where
T: Clone + Copy,
{
type Item = Rc<RefCell<Node<T>>>;
type IntoIter = LLCursor<T>;
fn into_iter(self) -> Self::IntoIter {
LLCursor {
cur: self.head.clone(),
}
}
}
impl<T> Iterator for LLCursor<T>
where
T: Copy,
{
type Item = Rc<RefCell<Node<T>>>;
fn next(&mut self) -> Option<Rc<RefCell<Node<T>>>> {
match self.cur.clone() {
Some(node) => {
self.cur = node.borrow().next.clone();
Some(node)
}
None => None,
}
}
}
我想创建一个函数,可以在迭代时访问链表节点的内容。像这样:
pub fn print(self)
where
List<T>: IntoIterator,
<List<T> as IntoIterator>::Item: std::fmt::Debug,
{
for i in self {
println!("{:?}", Some(i.borrow().clone().item));
}
}
错误:
error[E0599]: no method named `borrow` found for associated type `<List<T> as IntoIterator>::Item` in the current scope
--> src/list.rs:90:51
|
90 | println!("{:?}", i.borrow().clone().item);
| ^^^^^^ method not found in `<List<T> as IntoIterator>::Item`
|
= help: items from traits can only be used if the trait is in scope
= note: the following trait is implemented but not in scope; perhaps add a `use` for it:
`use std::borrow::Borrow;`
我了解 i
在这种情况下属于 <List<T> as IntoIterator>::Item
类型。我是生锈的新手,所以我看不出迭代器 returns 以这种方式关联的类型有何用处。我希望 i
是 Option<Rc<RefCell<Node<T>>>>
类型。有没有一种方法可以将其从关联类型中提取出来,以便我能够访问每个单独节点的元素?
None 的迭代器代码实际上需要 T: Copy
,我建议你删除它,因为它混淆了你的问题。那么,既然知道<List<T> as IntoIterator>::Item
其实就是T
,那么就可以直接使用了:
pub fn print(self) where T: Debug {
for i in self {
println!("{:?}", i.borrow().item);
}
}
我还在打印时删除了 .clone()
,因为它是不必要的,并且避免了 T: Clone
约束。看到它在 playground.
你得到错误的原因是因为约束 List<T>: IntoIterator
和 Item: Debug
并不意味着 Item
是 Rc<RefCell<_>>
。您需要一个额外的约束 T: Copy
才能推断出正确的 IntoIterator
实现。就您演示的代码而言,不存在其他实现,但理论上存在不冲突的实现可能,并且编译器不会进行猜测。
作为旁注,对 Self
类型(此处明确表示为 List<T>
)的约束非常少见,除非在特征中,因为您通常知道 Self
需要什么来满足这些限制,并且直接列出它更具描述性。 (即,如果 Self
需要 Clone
,但您知道 Self
是 Clone
如果 T
是 Clone
,您将使用 T: Clone
作为约束)。