将 String 转换为 &str 的惯用方法是什么?

What is the idiomatic way to convert a String to &str?

我找到了多种将 String 转换为 &str 的方法。 correct/idiomatic 今天是哪一个?

let string = "hello".to_string();

let string_slice1 = &string[..];
let string_slice2: &str = &string;
let string_slice3 = &*string;

如何在不在变量声明中指定类型的情况下使第二种方法起作用?像 &string as &str 这样的东西(但它不起作用)。我看到 &string&String 类型,但是当它隐式转换为 &str 时,它将执行隐式转换。我如何明确转换?

String 实现了两个重要的东西:

  • Index<RangeFull, Output = str>:这使得 string[..] 成为 str 类型,尽管您需要引用它(通过调用方法,允许 autoref发生,或明确表示为 &string[..])。这解释了 string_slice1.

  • Deref<Target = str>:这使得 *string 成为 str 类型,与在索引中一样考虑未确定大小的类型。这就是 string_slice3 起作用的原因,以及 string_slice2 起作用的一些隐藏行为。

与 C++ 不同,& 不是纯引用运算符:它还允许首先进行取消引用。因此 &string 通常是 &String 类型,但如果需要也可以是 &str 类型。例如,如果您要将它传递给采用 &str 的方法,它会起作用,或者如果您尝试将它绑定到 &str 类型的变量。这就是为什么 : &str 对于这种情况是必要的。

普遍的共识是在可行的情况下应避免类型归属,因此第二种形式不可取。第一个和第三个之间,对于哪个更可取还没有达成共识。

还有 String::as_str,有些人更喜欢:

let string_slice4 = string.as_str();