< 返回版块

qianjunjushi 发表于 2019-07-23 09:47

Tags:deref

我在看rust编程语言 里面智能指针章节第一部分

# use std::ops::Deref;
#
# struct MyBox<T>(T);
#
# impl<T> MyBox<T> {
#     fn new(x: T) -> MyBox<T> {
#         MyBox(x)
#     }
# }
#
# impl<T> Deref for MyBox<T> {
#     type Target = T;
#
#     fn deref(&self) -> &T {
#         &self.0
#     }
# }
#
# fn hello(name: &str) {
#     println!("Hello, {}!", name);
# }
#
fn main() {
    let m = MyBox::new(String::from("Rust"));
    hello(&m);
}

书上原文 这里使用 &m 调用 hello 函数,其为 MyBox 值的引用。因为示例 15-10 中在 MyBox 上实现了 Deref trait,Rust 可以通过 deref 调用将 &MyBox 变为 &String。标准库中提供了 String 上的 Deref 实现,其会返回字符串 slice,这可以在 Deref 的 API 文档中看到。Rust 再次调用 deref 将 &String 变为 &str,这就符合 hello 函数的定义了


我的疑问就是 Rust 可以通过 deref 调用将 &MyBox 变为 &String。 这一步我没法理解啊 以为 我理解的deref 就是一种对* 的重载 正如 书上面所说 *y 等效于 *(y.deref()) 但是这个关& 什么事情啊 &MyBox 怎么就转变为 &String 求大神为我解惑

评论区

写评论
plus7wist 2019-08-02 13:11

Deref 这个 Trait 是这样子的:

pub trait Deref {
    type Target: ?Sized;
    fn deref(&self) -> &Self::Target;
}

当实现了 Deref 的类型调用 deref,得到的不是 Target 本身,而是 Target 的借用。

MyBox 实现的 DerefTargetString*m 就会得到 String,我认为这个过程其实是 *m.deref(),也就是说 deref 不是解引用本身,而是返回可以被解引用的对象的借用。我认为这样设计有它的合理性。

从这个角度看,说 &MyBox 转换成了 &String 就是可以理解的了。

zhubaiyuan 2019-07-26 15:45

调用 hello 函数,它需要接受的参数是 &str。

实际参数 &MyBox::new(String::from("Rust”)) 不是 &str,还找不到 hello() 方法,Rust 提供了自动解引用机制,于是 Rust 编译器帮我们对 MyBox 做隐式的 deref 调用,输出 &String;

仍然找不到 hello() 方法,标准库中实现了 String 向 str 的解引用转换,它的签名是 fn deref(&self) -> &str, 于是继续做隐式的 deref 调用,输出 &str,这样就可以对 &str 调用 hello 函数了。

作者 qianjunjushi 2019-07-23 10:26

对以下内容的回复:

非常感谢您的回答

您上面说的 只有对box 进行 *操作的时候 才会返回 *(&self.0) 但是对box 进行 &操作的时候 发生了什么转换呢

好的 谢谢

simoin 2019-07-23 10:23

MyBox实现了Deref, 就能强制隐式转换,将MyBox的引用转换成Target

对以下内容的回复:

非常感谢您的回答

您上面说的 只有对box 进行 *操作的时候 才会返回 *(&self.0) 但是对box 进行 &操作的时候 发生了什么转换呢

作者 qianjunjushi 2019-07-23 10:06

对以下内容的回复:

非常感谢您的回答

您上面说的 只有对box 进行 *操作的时候 才会返回 *(&self.0) 但是对box 进行 &操作的时候 发生了什么转换呢

simoin 2019-07-23 09:55

self.0 不就是了么

https://doc.rust-lang.org/stable/rust-by-example/generics/new_types.html

1 共 6 条评论, 1 页