为什么在Rust中String会隐式转换为&str?

4

考虑以下代码:

let s = String::from("hello");
let mut r = String::new();

for c in s.chars() {
    r.push(c);
}

作为&str的方法,为什么String可以调用chars方法呢?我想这可能与coercion(强制类型转换)有关,但是我并不完全理解这个隐式转换。

1
具体的解释在String文档中。 - edwardw
2
@chenzhongpu "在查找方法调用时,接收器可能会自动取消引用或借用以调用方法。" (https://doc.rust-lang.org/reference/expressions/method-call-expr.html) - Denys Séguret
明白,@DenysSéguret - chenzhongpu
1
请参阅书中更长的Deref强制转换解释:https://doc.rust-lang.org/book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods - Jussi Kukkonen
1
《Rust 的自动解引用规则是什么?》 这篇文章回答了你的问题吗? - trent
显示剩余2条评论
1个回答

2
这实际上在这个问题中已经涉及到了:Rust的自动解引用规则是什么?。那个答案中有很多内容,所以我将尝试将其应用到您的问题上。
引用huon的回答:“
算法的核心是:
- 对于每个"解引用步骤"U(即,设置U = T,然后U = *T,...)
  1. 如果存在一个方法bar,其接收者类型(方法中的self的类型)与U完全匹配,则使用它(一个“按值传递方法”
  2. 否则,添加一个自动引用(取&&mut的接收者),如果某个方法的接收者与&U匹配,则使用它(一个“自动引用方法”
关键在于“取消引用步骤”: U = *T 意味着 let u = Deref::deref(t);,其中 u: Ut: T。我们一直这样做,直到无法再取消引用为止。
按照该算法对你代码中的 s.chars() 调用进行如下处理:
  1. 第一次取消引用(没有取消引用):
    1. 你能调用 String::chars(s) 吗?不能。
    2. 那么 &String 或者 &mut String 呢?也不行。
  2. 第二次取消引用: <String as Deref>::Target = str,因此我们正在查找 str 的方法。 let c: str = *s(假设允许该 DST 类型);
    1. 你能调用 str::chars(c) 吗?不能
    2. 你能调用 str::chars(&c) 吗?可以!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接