为什么String :: from(* d)在&& str上给出了* d.to_string()的不同结果?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么String :: from(* d)在&& str上给出了* d.to_string()的不同结果?相关的知识,希望对你有一定的参考价值。

我有点疑惑为什么在第二种情况下解除引用&&str似乎不起作用:

use std::collections::HashSet;

fn main() {
    let days = vec!["mon", "tue", "wed"];
    let mut hs: HashSet<String> = HashSet::new();

    for d in &days {
        // works
        hs.insert(String::from(*d));

        // doesn't
        hs.insert(*d.to_string());
    }
    println!("{:#?}", hs);
}

str确实实现了ToString特性,但它仍然给我错误:

error[E0308]: mismatched types
  --> src/main.rs:12:19
   |
12 |         hs.insert(*d.to_string());
   |                   ^^^^^^^^^^^^^^ expected struct `std::string::String`, found str
   |
   = note: expected type `std::string::String`
              found type `str`

我在这里弄错了什么语法?

Rust Playground Link

答案

to_string在它被解雇之前被召唤到d,所以你将dez the String,这导致str

将其更改为

hs.insert(d.to_string());

这是有效的,因为d会自动解析为str,之后将转换为String。这叫做Deref coercions

如果你有一个类型U,它实现Deref<Target=T>&U的值将自动强制到&T

...

Deref也会在调用方法时启动

这是exactly the case hereimpl Deref<Target = str> for String。见here for an example

类型为&&&&&&&&&&&&&&&&Foo的值仍然可以在Foo上调用定义的方法,因为编译器将根据需要插入尽可能多的*操作以使其正确。因为它插入*s,使用Deref

这个example证明了这一点:

struct Foo;

impl Foo {
    fn foo(&self) { println!("Foo"); }
}

let f = &&Foo;

// prints "foo"
f.foo();

顺便说说,

hs.insert((*d).to_string());

也将work,因为它首先对&str deref'd。

以上是关于为什么String :: from(* d)在&& str上给出了* d.to_string()的不同结果?的主要内容,如果未能解决你的问题,请参考以下文章

2022-08-05:以下go语言代码输出什么?A:65, string;B:A, string;C:65, int;D:报错。

1119. Remove Vowels from a String - Easy

A prepared statement is generated from a nonconstant String 问题的解决

IllegalArgumentException: Can not create a Path from an empty string

Cannot get a STRING value from a NUMERIC cell poi异常解决

Python 解LeetCode:606 Construct String from Binary Tree