Copyright © 2022-2024 aizws.net · 网站版本: v1.2.6·内部版本: v1.23.3·
页面加载耗时 0.00 毫秒·物理内存 61.8MB ·虚拟内存 1299.8MB
欢迎来到 AI 中文社区(简称 AI 中文社),这里是学习交流 AI 人工智能技术的中文社区。 为了更好的体验,本站推荐使用 Chrome 浏览器。
在一些特定场景中,类型会被隐式地强制转换。这种转换通常导致类型被“弱化”,主要针对指针和生命周期。主要目的是让Rust适用于更多的场景,并且基本上是无害的。
强制转换包括下面几种:
如下几种类型之间允许进行强制转换:
T_1
可以强制转换为T_2
且T_2
可以强制转换为T_3
时,T_1
就可以强制转换为T_3
&mut T
转换为&T
*mut T
转换为*const T
&T
转换为*const T
&mut T
转换为*mut T
T
实现了CoerceUnsized<U>
,那么T
可以强制转换为U
T
可以解引用为U
(比如T: Deref<Target=U>
),那么&T
类型的表达式&x
可以强制转换为&U
类型的&*x
所有的指针类型(包括Box和Rc这些智能指针)都实现了CoerceUnsized<Pointer<U>> for Pointer<T> where T: Unsize<U>
。Unsize只能被自动实现,并且实现如下转换方式:
[T; n]
=> [T]
T
=> Trait
,其中T: Trait
Foo<..., T, ...>
=> Foo<..., U, ...>`,其中
T: Unsize<U>
Foo
是一个结构体Foo
的最后一个成员是和T
有关的类型T
无关Bar<T>
,那么必须有Bar<T>: Unsize<Bar<U>>
强制转换会在“强制转换位置”处发生。每一个显式声明了类型的位置都会引起到该类型的强制转换。但如果必须进行类型推断,则不会发生类型转换。表达式e
到类型U
的强制转换位置包括:
let x: U = e
takes_a_U(e)
fn foo() -> U {e}
Foo { some_u: e }
let x: [U; 10] = [e, ...]
let x: (U, ..) = (e, ..)
let x: U = { ..; e }
注意,在匹配trait的时候不会发生强制类型转换(receiver除外,具体见下)。也就是说,如果为U
实现了一个trait,T
可以强制转换为U
,并不能认为T
也实现了这个trait。例如,下面的代码无法通过类型检查,虽然t
可以强制转换为&T
,而且有一个&T
的trait实现。
trait Trait {} fn foo<X: Trait>(t: X) {} impl<'a> Trait for &'a i32 {} fn main() { let t: &mut i32 = &mut 0; foo(t); }
<anon>:10:5: 10:8 error: the trait bound `&mut i32 : Trait` is not satisfied [E0277] <anon>:10 foo(t); ^~~
点操作符可以做到许多神奇的类型转换任务,比如自动引用,自动解引用,还有级联类型匹配后的强制类型转换。TODO:从这里偷一些信息 stackoverflow.com/questions/2851999...