vectores una que programacion matriz matrices informatica entre ejemplos diferencia cual arreglos arreglo array arrays rust slice coercion

arrays - que - ¿Cuál es la diferencia entre un sector y una matriz?



que es un vector y una matriz en programacion (2)

¿Por qué tanto &[u8] como &[u8; 3] &[u8; 3] ok en este ejemplo?

fn main() { let x: &[u8] = &[1u8, 2, 3]; println!("{:?}", x); let y: &[u8; 3] = &[1u8, 2, 3]; println!("{:?}", y); }

El hecho de que &[T; n] &[T; n] puede forzar a &[T] es el aspecto que los hace tolerables. - Chris Morgan

¿Por qué puede &[T; n] &[T; n] coaccionar a &[T] ? ¿En qué otras condiciones se produce esta coacción?


¿Por qué puede &[T; n] &[T; n] coaccionar a &[T] ?

La otra respuesta explica por qué &[T; n] &[T; n] debería coaccionar a &[T] , aquí explicaré cómo funciona el compilador que &[T; n] &[T; n] puede coaccionar a &[T] .

Hay cuatro posibles coerciones en Rust :

  1. Transitividad.

    • Si T coerces a U y U coercen a V , entonces T coerces a V
  2. Debilitamiento del puntero

    • eliminando la mutabilidad: &mut T&T y *mut T*const T
    • conversión a puntero sin formato: &mut T*mut T y &T*const T
  3. Deref rasgo :

    • Si T: Deref<Target = U> , entonces &T obliga a &U través del método deref()
    • (De manera similar, si T: DerefMut , entonces &mut T coerces a &mut U través de deref_mut() )
  4. Rasgo de Unsize

    • Si Ptr es un "tipo de puntero" (por ejemplo, &T , *mut T , Box , Rc , etc.) y T: Unsize<U> , Ptr<T> obliga a Ptr<U> .

    • El rasgo Unsize se implementa automáticamente para:

      • [T; n]: Unsize<[T]>
      • T: Unsize<Trait> donde T: Trait
      • struct Foo<…> { …, field: T }: Unsize< struct Foo<…> { …, field: U }> , siempre que T: Unsize<U> (y algunas condiciones más para facilitar el trabajo al compilador )
    • (Rust reconoce a Ptr<X> como un "tipo de puntero" si implementa CoerceUnsized . La regla real se establece como " si T: CoerceUnsized<U> entonces T coerces a U ".)

La razón &[T; n] &[T; n] obliga a &[T] es la regla 4: (a) el compilador genera el implemento Implementar impl Unsize<[T]> for [T; n] impl Unsize<[T]> for [T; n] para cada [T; n] [T; n] , y (b) la referencia &X es un tipo de puntero. Usando estos, &[T; n] &[T; n] puede coaccionar a &[T] .


[T; n] [T; n] es una matriz de longitud n , representada como n instancias T adyacentes.

&[T; n] &[T; n] es puramente una referencia a esa matriz, representada como un puntero delgado a los datos.

[T] es una porción, un tipo sin tamaño; Solo se puede utilizar a través de alguna forma de direccionamiento indirecto.

&[T] , llamado sector, es un tipo de tamaño. Es un puntero grueso , representado como un puntero al primer elemento y a la longitud de la rebanada.

Por lo tanto, las matrices tienen su longitud conocida en tiempo de compilación, mientras que las longitudes de corte son una cuestión de tiempo de ejecución. Las matrices son ciudadanos de segunda clase en la actualidad en Rust, ya que no es posible formar genéricos de matriz. Existen implementaciones manuales de los diversos rasgos para [T; 0] [T; 0] , [T; 1] [T; 1] , & c. , típicamente hasta 32; Debido a esta limitación, los cortes son mucho más útiles en general. El hecho de que &[T; n] &[T; n] puede forzar a &[T] es el aspecto que los hace tolerables.

Hay una implementación de fmt::Debug para [T; 3] [T; 3] donde T implementa Debug , y otro para &T donde T implementa fmt::Debug , y así como u8 implementa Debug , &[u8; 3] &[u8; 3] también lo hace.

¿Por qué puede &[T; n] &[T; n] coaccionar a &[T] ? En Rust, ¿cuándo ocurre la coacción?

Se coaccionará cuando sea necesario y en ningún otro momento. Puedo pensar en dos casos:

  1. donde algo espera un &[T] y le das un &[T; n] &[T; n] coercirá silenciosamente;
  2. cuando llama a x.starts_with(…) en un [T; n] [T; n] observará que no existe tal método en [T; n] [T; n] , y así entra en juego el autoref y lo intenta &[T; n] &[T; n] , que no ayuda, y luego la coacción entra en juego e intenta &[T] , que tiene un método llamado starts_with .

El fragmento [1, 2, 3].starts_with(&[1, 2]) muestra ambos.