在Rust中,From::from和as之间有什么区别?

27

我可以使用fromas来在类型之间进行转换:

i64::from(42i32);
42i32 as i64;

这些之间有什么不同?

1个回答

45

as只能在一小部分固定的转换中使用。参考文档as

as可以用于显式执行强制类型转换,以及以下附加的转换。这里*T表示*const T*mut T。 | e的类型 | U | e as U执行的转换 | | --- | --- | --- | | 整数或浮点数类型 | 整数或浮点数类型 | 数值转换 | | 类C枚举 | 整数类型 | 枚举转换 | | boolchar | 整数类型 | 基本类型到整数的转换 | | u8 | char | u8char的转换 | | *T | *V,其中V: Sized * | 指针到指针的转换 | | *T,其中T: Sized | 数字类型 | 指针到地址的转换 | | 整数类型 | *V,其中V: Sized | 地址到指针的转换 | | &[T; n] | *const T | 数组到指针的转换 | | 函数项 | 函数指针 | 函数项到函数指针的转换 | | 函数项 | *V,其中V: Sized | 函数项到指针的转换 | | 函数项 | 整数 | 函数项到地址的转换 | | 函数指针 | *V,其中V: Sized | 函数指针到指针的转换 | | 函数指针 | 整数 | 函数指针到地址的转换 | | 闭包 ** | 函数指针 | 闭包到函数指针的转换 |
* 或TV是兼容的非精确类型,例如两个切片,两个相同的trait对象。
** 仅适用于不捕获(关闭)任何局部变量的闭包

因为as是编译器已知且仅适用于特定转换的,所以它可以进行某些类型的更复杂的转换。

From是一个trait,这意味着任何程序员都可以为其自己的类型实现它,并且因此可以应用于更多的情况。它与{{Into相配对。TryFromTryInto自Rust 1.34以来已经稳定。

由于它是一个trait,因此可以在通用上下文中使用(fn foo(name: impl Into<String>) { /* ... */ })。这对于as来说是不可能的(尽管请参见num包中的{{AsPrimitive)。

在转换数字类型时,需要注意的一件事是,From 仅适用于无损转换(例如,您可以使用 Fromi32 转换为 i64,但反过来不行),而 as 可用于无损和有损转换(如果转换有损,则会截断)。因此,如果您想确保不会意外执行有损转换,您可能更喜欢使用 From::from 而不是 as
另请参见:

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