Rust: 为什么不为&str提供Into<String>的实现?

3
考虑以下陈述:From<T> for U 意味着 Into<U> for Tsource

let t="abc"; 并注意到 t 的类型为 &str

每个人都使用过:let s=String::from(t);

因此我们有:From<&str> for String

根据上述蕴含关系,我们有:Into<String> for &str

然而,以下内容无法正常工作:

fn main(){
    let z="abc";
    let x = String::from(z);
    let s=&str::into(x);
}

我不明白的是什么?

2
请注意,存在String::from并不意味着String实现了From特质。 - jthulhu
你是指 let s = &str::into(z); 吗? - LeopardShark
你为什么相信“每个人都在使用String::from()”?就我个人而言,我使用.to_owned(),我知道很多人使用.to_string()或者.into()(但是<&str>::into()相对较少见,因为为什么要使用这种方式,当你可以使用方法语法呢?) - Chayim Friedman
@jthulhu 嗯,我想如果不是这样的话,那就有点不寻常了。 - Chayim Friedman
@ChayimFriedman 我的观点是,正如原帖可能不知道的那样,实现特质与其他语言中接口(或鸭子类型)的工作方式不同,特质要求具有相同的方法来实现特质并不足够。我的观点并不是具有from关联函数的类型通常不这样做是因为它们实现了From特质。 - jthulhu
2个回答

8
它是有效的,只是&str::into(z)被理解为&(str::into(z))。如果你想调用与类型&str相关联的函数into,你必须使用限定名称来表示该类型:
fn main() {
    let z = "abc";
    let x = String::from(z);
    let s: String = <&str>::into(z);
}

请注意,类型注释String是因为否则Rust无法知道into的目标类型。
另外,您也可以使用方法语法。
    let s: String = z.into();

或者与特质 Into 相关的功能:
    let s: String = Into::into(z);

为什么 &str::into(z) 被理解为 &(str::into(z))? - user22447547
@Brett 这只是操作符优先级的设计方式。根据参考资料,路径(即::)比一元运算符(即&)具有更高的优先级。而且,你只能在标识符上使用::&str不是标识符,但str是),除非你使用<...>:: - kmdreko
@Brett 另外,& 不能作为路径的一部分。如果你需要给一个类型命名,而不是一个标识符,你需要用 <> 将其包裹起来。 - jthulhu
1
@jthulhu 你的 main() 函数无法编译通过。 - user22447547
@Brett 看起来只是一个简单的打字错误(他们在应该使用 z 的地方使用了 x)。我已经纠正了它。 - cdhowie

2
你有点迷失了方向。我经常在来回转换的时候也会这样;)
让我们考虑一下类型。`x` 是 `String` 类型。所以 `into(x)` 会尝试将一个 `String` 转换为 `&str`,但是你不能这样做。
事实上,`String` 实现了 `From<&str>`,这意味着 `&str` 实现了 `Into`,也就是说,你可以将一个 `&str` 转换为 `String`。
这才是你真正想要的:
fn main() {
    let x: &str = "abc";
    let z: String = String::from(x);
    
    let s: String = x.into();
}

没问题!

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