为什么 Into<String> 可以接受 String 类型?

5
struct Person {
    name: String,
}

impl Person {
    fn new<S: Into<String>>(name: S) -> Person {
        Person { name: name.into() }
    }
}

fn main() {
    let person = Person::new("test");
    let person = Person::new("test".to_string());
}

&str拥有Into<String> trait,因此我理解我可以正确地调用Person::new("test")

但是,我认为Person::new("test".to_string())会失败,因为String没有From<String> for String,所以Into<String>不能自动派生。
为什么我可以调用Person::new("test".to_string())

此外,我也可以调用以下代码:

let test: String = String::from("test".to_string());

在上述情况下,即使 String 没有实现 From<String> for String,我仍然可以成功调用 String::from("test".to_string()),这一点我无法理解。

4
文档说:_Into 是自反的,也就是说对于 T,实现了 Into<T>。_ - John Ledbetter
有时您会看到它表达为 fn new<S>(name: S) -> Person where S : Into<String>,以使声明更紧凑。 - tadman
1
更好的是 fn new(name: impl Into<String>) - Ibraheem Ahmed
1个回答

6

然而,我认为Person::new("test".to_string())失败是因为String没有From<String> for String,所以Into不能自动推导。

实际上,From(因此也包括Into)是自反的:

// https://doc.rust-lang.org/src/core/convert/mod.rs.html#545-549

impl<T> From<T> for T {
    fn from(t: T) -> T {
        t
    }
}

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