为什么对数组的嵌套引用不会强制切片?

Ken*_*ima 6 coercion dereference rust

我读过什么是Rust的确切自动解除引用规则?从头到尾,但我仍然有一个关于从数组到切片的强制的问题.

让我们考虑以下代码:

let arr: &[i32; 5] = &&&[1, 2, 3, 4, 5];
// let arr: &[i32] = &&&[1, 2, 3, 4, 5]; // Error; expected slice, found reference
Run Code Online (Sandbox Code Playgroud)

我希望它&&&[1, 2, 3, 4, 5]有类型,&&&[i32; 5]并且引用 &&[i32; 5]=> &[i32; 5]=> &[i32; 5]=> &[i32],但结果与我的预期不同.

我试着运行以下代码:

let arr: &&&[i32; 5] = &&&[1, 2, 3, 4, 5];
let n = arr.first().unwrap(); // 1
Run Code Online (Sandbox Code Playgroud)

这是正确的代码.arr强制类型为&&&[i32; 5]=> &&[i32; 5]=> &[i32; 5]=> &[i32]并匹配first切片中的第一个参数,&self.

数组强制切片的条件是什么?我不明白前者和后者代码之间的区别.

我还检查了源代码中的文档,并猜测上面的问题与下面引用的句子有关;

然而,我们有时会在此过程中进行其他调整和强制,特别是未经过调整(例如,从[T; n]转换为[T]).

tre*_*tcl 8

这种胁迫旨在起作用,但没有实施.

数组没有实现Deref,因此强制&[T; n] -> &[T]不是一种deref强制,并且不能以一种方式工作.相反,它被称为"未确定的强制",因为它将大小的类型([T; n])转换为未大小的类型([T]).

也就是说,语言参考(不是规范性的,可能已经过时,但对我而言)列出了可能的强制措施,包括:

  • T_1T_3哪里T_1强迫T_2T_2胁迫T_3(传递案件)

    请注意,尚未完全支持此功能

  • &T&U如果T工具Deref<Target = U>.
  • TyCtor(T)到TyCtor(U),其中TyCtor(T)是其中之一

    • &T
    • &mut T
    • *const T
    • *mut T
    • Box<T>

    在哪里T可以U通过未经证实的强制来获得.

最后一个子弹,未经证实的强制,是允许&[T; n]强迫的&[T].值得注意的是,这仅描述了一层引用; 它不包括&&[T; n]- > &[T]案例(我们也需要Deref强制).

回到你的非工作范例:

let arr: &[i32] = &&&[1, 2, 3, 4, 5];
Run Code Online (Sandbox Code Playgroud)

预期的强制是&&&[i32; 5]- > &[i32].我们可以弄清楚这种强制应该如何运作:

  1. &[i32; 5]强制转换到&[i32]由unsizing;
  2. &&[i32; 5]强制转换到&[i32; 5]通过Deref;
  3. 因此,通过传递性&&[i32; 5]来强迫.&[i32]
  4. &&&[i32; 5]强制转换到&&[i32; 5]通过Deref;
  5. 因此,通过传递性&&&[i32; 5]来强迫.&[i32]

但事实并非如此.上面的引用暗示了原因:在传递的情况下,它说"请注意,这还没有完全支持".据我所知,根据问题#18602,"不完全支持"是一种对冲; 说"未实现"会更准确.所以,就目前而言,通过传递性的强制是不可能的.显然这个问题不是一个高优先级,可能是因为大小的数组并不常见.(我怀疑当const泛型登陆时,这可能会成为一种更常见的抱怨,因为这可能会使数组更有用.)

那么,为什么 arr.first()工作呢?好吧,用于查找用(点)运算符调用的方法的"自动解除引用规则"是强制规则.扩展.Autoderef类似于手动解除引用任何次数,直到您使用给定方法获得某些内容(可以强制转换为某种类型).这意味着您不需要传递性来通过autoderef(RFC 401称为"接收器强制")来查找方法调用.


进一步阅读

RFC#401描述了大多数强制的预期语义.这个RFC在4年前就被合并了.从那时起,许多事情都发生了变化,但仍未完全实现(其跟踪问题是#18469),因此RFC 401无法准确描述Rust的任何过去,现在或未来版本.然而,RFC 401 将允许胁迫&&&[i32; 5]&[i32]并用几乎同样的逻辑.

Rustonomicon也有强制转换一章,并出现与参考书同意.