将字符串转换为&str的惯用方法是什么?

28

我找到了几种将 String 转换为 &str 的方法。今天哪种方法是正确的/惯用的?

let string = "hello".to_string();

let string_slice1 = &string[..];
let string_slice2: &str = &string;
let string_slice3 = &*string;
我怎样可以在不指定变量类型的情况下让第二种方法起作用?类似于&string as &str(但它不起作用)。我看到&string&String类型,但当它被隐式转换为&str时,它将执行隐式转换。我怎样才能使这种转换显式?
1个回答

36

这里有两个String实现的重要事项:

  • Index<RangeFull, Output = str>:这使得string[..]的类型为str,尽管您需要对它进行引用(通过调用方法,允许自动引用或显式地使用&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();

2
然而,如果不需要类型注释,即在可以推断出&str的上下文中,例如在将参数传递给非泛型函数时,第二种形式更好。 - user395760
"... & 不是一个纯引用运算符:它还允许先进行解引用。" 你的意思是在第二种情况下,应该这样写:let string_slice2: &str = &(*string);吗? - Ta Thanh Dinh

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