Est-il vrai que pour tous les types «T», «U» si «T» est forcé à «U» alors «& T» est forcé à «& U»?

Aug 17 2020

C'est bien documenté qui [T; n]peut contraindre [T]. Le code suivant est également bien formé :

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

Ici, nous avons cela &[T; n]est contraint &[T].

Est-il vrai que pour tous les types T, Usi Test forcé de le faire, Ualors &Test-il contraint &U?

Ce n'est pas documenté dans la référence (du moins explicitement).

Réponses

5 trentcl Aug 17 2020 at 19:54

Non, car l'ajout d'une couche supplémentaire &entraîne son échec:

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]`

De plus, ce n'est pas le cas qui [T; n] contraint [T] dans le même sens que celui qui &[T; n] contraint &[T] . La documentation que vous avez liée décrit les deux caractéristiques liées aux coercitions non dimensionnées: Unsizeet CoerceUnsized. [T; n]met en œuvre Unsize<[T]>, et donc &[T; n] implémente CoerceUnsized<&[T]>; c'est essentiellement la même chose et votre code démontre efficacement les deux. Il ne serait pas possible d'écrire une fonction qui contraint [T; n]à [T] sans l' aide de références (ou des pointeurs de quelque sorte) parce que coercitions unsizing ne prennent place derrière une sorte de pointeur.