Верно ли, что для всех типов `T`,` U`, если `T` приводится к` U`, то `& T` приводится к` & U`?

Aug 17 2020

Это хорошо задокументировано, что [T; n]можно принуждать [T]. Следующий код также имеет правильный формат :

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

Здесь мы имеем то &[T; n], к чему принуждено &[T].

Верно ли, что для всех типов T, Uесли Tк чему-то принуждают, Uто &Tпо принуждению &U?

Это не задокументировано в справочнике (по крайней мере, явно).

Ответы

5 trentcl Aug 17 2020 at 19:54

Нет, потому что добавление еще одного слоя &приводит к сбою:

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] в том же смысле, что и &[T; n] принуждают &[T] . Связанная вами документация описывает две особенности, связанные с некорректным приведением: Unsizeи CoerceUnsized. [T; n]орудия Unsize<[T]>и, следовательно, &[T; n] орудия CoerceUnsized<&[T]>; По сути, это одно и то же, и ваш код эффективно демонстрирует и то, и другое. Это не было бы возможно , чтобы написать функцию , которая принуждает [T; n]к [T] без использования ссылок (или указатели какого - то) , потому что unsizing только приведения типов иметь место за какое - то указатель.