Too-many-lists: 解释`&**节点`

创建于 2015-08-10  ·  10评论  ·  资料来源: rust-unofficial/too-many-lists

https://www.reddit.com/r/rust/comments/3geb5q/learning_rust_with_entirely_too_many_linked_lists/ctxgwmz ,也许可以解释&**node以使其更明显地被取消引用。 来自C,这有点令人困惑。

最有用的评论

我在操场上尝试了@m-ou-se 的建议: https : =7156f8fdd1d3c883379b5de868f230be

好奇,我去阅读Box::deref

impl<T: ?Sized> Deref for Box<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &**self
    }
}

我相信这可以与take()map()

顺便说一句,更通用的Deref::deref也有效。

所有10条评论

感谢您记录问题:+1:

只是偶然发现了这一点,我什**3.5 iter中的第 369 行(或在“(ノಥ益ಥ)ノ ┻━┻ ”之后) 中发现新的**并且非常惊讶在最终代码中看到它。

我也没有完全理解我们需要as_ref()是不是太明显

我正在浏览本节,第 259 行的&**node应该是&*node吗? 我可能漏掉了一些东西,但我没有看到它从上一节改变的理由。

https://github.com/Gankro/too-many-lists/blame/master/text/second-iter.md#L259

第 123123 行错误中的类似问题。

https://github.com/Gankro/too-many-lists/blame/master/text/second-iter.md#L123

记住我们在Iter::next想要的是Option<&Node<T>>&是引用,而*是取消引用,就像在 C 中一样。

self.headOption<Box<Node<T>>>所以没有as_ref()map() nodeBox<Node<T>> 。 一种取消引用, * ,摆脱Box<>并取出Node<T> 。 然后我们用&引用它。

但是,随着as_ref()返回Option<&Box<Node<T>>> ,在map() node变成了&Box<Node<T>>&一个取消引用和Box<>另一个取消引用,需要两次取消引用才能取出Node<T> 。 然后用&引用它。

@马克威克
恕我直言,主题是我们不能简单地将结果移出Option<> 。 我们要么使用take()map()它,要么使用as_ref()查看它。 如果我们将它与map()但只返回一个引用,则一旦返回引用,节点本身就会超出范围。 所以我们必须首先查看它as_ref() ,然后map()引用出来以取消引用节点。

为了与本书的主题保持一致,在添加as_ref然后修复它并解释原因之后,该部分可能会有另一个编译器因类型不匹配而向我们尖叫的情况。 此外,在需要进行更改之前,文本中有几个部分会剧透并显示**

在查看“官方”解决方案之前,我仍在阅读本书,并始终尝试自己实现当前功能(例如.iter() )(仅使用 Rust 文档)。 我的iter()最终看起来有点不同:

pub struct List<T> {
    head: Link<T>,
}

type Link<T> = Option<Box<Node<T>>>;

struct Node<T> {
    elem: T,
    next: Link<T>,
}

impl<T> List<T> {
    // [...]

    pub fn iter(&self) -> Iter<T> {
        Iter(&self.head)
    }
}

pub struct Iter<'a, T: 'a>(&'a Link<T>);

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.as_ref().map(|node| {
            self.0 = &node.next;
            &node.elem
        })
    }
}

不知道这是任何更好或更坏,但它摆脱两者的&**还有.map()呼叫List::iter() ,这感觉就像代码的重复在Iter::next()给我。

编辑:不幸的是,我正在努力为iter_mut()使用相同的方法:(

使用.map(Box::deref)而不是.map(|node| &**node)可能更清楚。

我刚刚发布了一个重大更新,修复此问题是其中一项更改。

(虽然使用 Box::deref 很有趣)

我在操场上尝试了@m-ou-se 的建议: https : =7156f8fdd1d3c883379b5de868f230be

好奇,我去阅读Box::deref

impl<T: ?Sized> Deref for Box<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &**self
    }
}

我相信这可以与take()map()

顺便说一句,更通用的Deref::deref也有效。

嗨,我今天正在学习教程,偶然发现了这一章……我的解决方案如下:

Iter { next: self.head.as_ref().map(|boxed_node| boxed_node.as_ref()) }

我不知道人们是否通常通过* &手动取消引用*但为此目的添加另一个*似乎有些不自然,最重要的是,生成的代码看起来并不对我来说很容易理解。

其实我也只是继续阅读Box.as_ref()

#[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
impl<T: ?Sized> AsRef<T> for Box<T> {
    fn as_ref(&self) -> &T {
        &**self
    }
}

我认为Box::derefBox.as_ref都应该优先于教程中的当前解决方案

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

kontrafiktion picture kontrafiktion  ·  9评论

Gankra picture Gankra  ·  3评论

louy2 picture louy2  ·  5评论

wthrowe picture wthrowe  ·  3评论

spacejam picture spacejam  ·  3评论