从一个有趣的功能开始。
let slice = "Hello, world!";
let str = String::from(slice);
类型转换的写法很像是C++自定义类型强制类型转换函数。
其实可以有另一种写法。
let str2: String = slice.into();
第三个现象,是String的From<T>只实现了从&str类型到自身的转换,因此不能把整型换成String。
let num = 5;
let str = num.to_string();
这是因为String需要经常被使用在输出类型信息中,能Debug基本就需要能变为String。但是这些类型却不和String有紧密联系,只需要能变为某种字符串形式。因此选择给类型实现to_string而非实现String::Form<T>。
impl和trait
从From<T>的实现,可以尝试学习impl和trait。
impl是为type提供功能的,impl中的函数,其参数为self的,就是成员函数的地位,调用时用.表示传入self;没有self参数的是静态函数的地位,调用时用::。
impl type可以念成类型的实现,module是不具有实现的。
-
to_string是一个传入了self的impl fn(成员fn)
-
from_utf8是一个未传入self的impl fn
-
from是trait fn(接口/虚基类的fn的实现)
-
into是trait fn
它们都在impl块中,前两个处于impl String块。
第三个处于impl From<&str> for String中,第四个处于impl Into<String> for &str中。
区别在于,第三个中为String实现trait From,是被编写的。trait From<T>: Sized是这个trait。
pub const trait From<T>: Sized {
fn from(value: T) -> Self
}
而第四个中是被推断的。trait Into<T>: Sized,形式和From一样,但是为类型手动实现Into通常是不必要的。因为存在一个推断实现:impl<T, U> Into<U> for T where U: From<T>。
pub const trait Into<T>: Sized {
fn into(self) -> T;
}
及其绕圈!所以请手写一遍&str转换到String的类型推断。
简单的翻译就是:如果U实现了From<T>,那么就为T实现Into<U>,两个trait里的两个fn,实现的都是从T到U的转换。U::from(T)和let U = T.into()是同一个方向上的。
zcxsb
有点缺乏结构性但是有点能看懂()