所有类型 `T` 和 `U` 是否都成立:如果将 `T` 强制转换为 `U`,那么 `&T` 是否会被强制转换为 `&U`?

4

文档中明确提到了 [T; n] 可以强制转换为 [T]。以下代码也是 合法的

fn test(){
    let _a: &[i32] = &[1, 2, 3];
}

在这里,我们将 &[T; n] 强制转换为 &[T]

对于所有类型的 TU,如果 T 被强制转换为 U,那么 &T 会被强制转换为 &U 吗?

这在参考文档中没有明确说明。


@PeterHall 这是真的,并且有很好的文档记录。问题是什么规则控制 &[T; n]&[T] 的转换? - Some Name
2
实际上,您链接的页面上已经有相关文档 - CoerceUnsized <&U> for &T 已经为 T: Unsize<U> 实现,这意味着您示例中的强制转换是存在的。 - Sven Marnach
在 Nomicon 中可能会更清晰一些:https://doc.rust-lang.org/nomicon/coercions.html - Sven Marnach
从同一页: 如果 T 实现了 Deref<Target = U>,则将 &T&mut T 转换为 &U - Peter Hall
@SvenMarnach 谢谢。如果您将其发布为答案,我会接受它。 - Some Name
1个回答

5
不行,因为再加一层&会导致它失败:
fn oops() {
    let a: &[i32; 3] = &[1, 2, 3];
    let _b: &&[i32] = &a;
}

error[E0308]: mismatched types
 --> src/lib.rs:8:23
  |
8 |     let _b: &&[i32] = &a;
  |             -------   ^^ expected slice `[i32]`, found array `[i32; 3]`
  |             |
  |             expected due to this
  |
  = note: expected reference `&&[i32]`
             found reference `&&[i32; 3]`

此外,[T; n] 并不像 &[T; n] 那样 强制转换成 [T]。您提供的文档描述了与无大小强制转换相关的两个特征:UnsizeCoerceUnsized[T; n] 实现了 Unsize<[T]>,因此&[T; n] 实现了 CoerceUnsized<&[T]>; 这本质上是相同的事情,您的代码有效地展示了两者。不使用引用(或某些类型的指针),不可能编写将[T; n] 强制转换为[T] 的函数,因为无大小强制转换只在某种类型的指针后发生。

3
基本上,未经大小调整的强制转换总是将某种类型的指针转换为一个胖指针。文档确实措辞有些令人困惑,需要改进。 - Sven Marnach

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