2015-11-24 15 views
11

The Rust Book section on the as operator attualmente diceQuali cast sono permessi con `as`?

La parola chiave come fa colata di base:

let x: i32 = 5; 

let y = x as i64; 

Esso consente solo certi tipi di casting, però.

Quali sono quelli determinati tipi di casting consentito?

Una risposta cancellata qui ha spiegato che a volte è necessario concatenare più as -cast per ottenere un risultato sicuro, che non può essere eseguito in un unico passaggio. Quando è necessario?

+1

FWIW, la documentazione di ruggine sono piuttosto sensibili alle questioni suggerendo miglioramenti. O ancora meglio, prendi la/e risposta/e qui e invia un PR ai documenti affinché tutti ne possano beneficiare! – Shepmaster

+1

Sì, stavo per fare proprio questo. – poolie

+0

Avviato in https://github.com/rust-lang/rust/pull/30088 – poolie

risposta

7

Non credo che questo è documentato molto bene, ma è here alcune informazioni che possono risultare utili:

un cast e as U è valida se una delle seguenti stive:

  • e ha tipo T e T con valore U; coercizione pressofuso
  • e ha tipo *T, U è *U_0, e sia U_0: Sized o unsize_kind (T) = unsize_kind (U_0); PTR-PTR pressofuso
  • e ha tipo *T e U è un tipo numerico, mentre T: Sized; PTR-addr pressofuso
  • e é un intero ed è U*U_0, mentre U_0: Sized; addr-PTR pressofuso
  • e ha tipo T e T e U sono eventuali tipi numerici; numeric-cast
  • e è un enum di tipo C e U è un tipo intero; enum pressofuso
  • e ha tipo bool o char e U è un numero intero; prim-int pressofuso
  • e ha tipo u8 e U è char; u8-char pressofuso
  • e ha tipo &[T; n] e U è *const T; array-PTR pressofuso
  • e è un tipo di puntatore funzione e U ha tipo *T, mentre T: Sized; fptr-ptr-cast
  • e è un tipo di puntatore a funzione e U è un numero intero; fptr-addr pressofuso

dove &.T e *T sono riferimenti di entrambi mutevolezza, e dove unsize_kind (T) è il tipo di informazioni unsize in T - vtable per una definizione di tratto (ad es fmt::Display oppure Iterator, non Iterator<Item=u8>) o una lunghezza (o () se T: Sized).

Si noti che le lunghezze non sono regolate in fase di lancio fette prime - T: *const [u16] as *const [u8] crea una fetta che include solo metà della memoria originale.

Casting non è transitiva, cioè, anche se e as U1 as U2 è un valido espressione, e as U2 non è necessariamente così (in realtà sarà valido solo se U1 costringe a U2).

+0

La trasmissione di un intero a un puntatore sembra non sicura. Forse questa lista non è più aggiornata dato che il documento dice che 'as 'fa solo cast sicuri (ora?) – poolie

+1

@poolie: funziona ancora [[playpen link] (http://is.gd/7sLMbt)]. il casting di un intero in un puntatore non è pericoloso ma il dereferenziamento di un puntatore lo è. – Adrian

2

Citato da The Rustonomicon: Casts

Ecco un elenco esaustivo di tutti i veri calchi. Per brevità, useremo * per indicare sia un * const o * mut e intero per indicare qualsiasi primitiva integrale:

  • * T come * U dove T, U: Sized
  • * T come * U TODO: spiegare situazione non calibrati
  • * T come intero
  • intero come * T
  • numero come numero
  • C-like-enum come intero
  • bool come numero intero
  • char come intero
  • u8 come char
  • & [T; n] come * const T
  • fn come * T dove T: Sized
  • fn come intero
+3

Come si differenzia questo elenco da quello già pubblicato? – Shepmaster

+0

È più facile da leggere per gli occhi. –