2015-06-12 18 views

risposta

30

UTF-8 non definisce quale "carattere" è così dipende da ciò che si desidera. In questo caso, char s sono valori scalari Unicode, quindi il primo char di uno &str sarà compreso tra uno e quattro byte.

Se si desidera solo il primo char, allora non raccogliere in un Vec<char>, basta usare l'iteratore:

let text = "hello world!"; 
let ch = text.chars().next().unwrap(); 
+3

Si potrebbe anche voler vedere se si desidera veramente il primo _grapheme_. – moveaway00

+1

Questo dà l'unità di codice 'n'th, ma' char_at' fornisce l'unità di codice che inizia con il byte 'n'. Quest'ultimo è più utile perché la maggior parte delle operazioni sulle stringhe si occupa degli indici di byte. Questo è equivalente a 'char_at' (e anche a tempo costante):' text [i ..]. Chars(). Next(). Unwrap() ' – delnan

+2

@delnan: direi che l'uso di' char_at' è leggermente pericoloso come l'indice potrebbe essere * in * un'unità di codice. –

-1

La risposta accettata è un po 'brutto!

let text = "hello world!"; 

let ch = &text[0..1]; // this returns "h" 
+0

Questa risposta è ** completamente errata ** per dati non ASCII. Prova '&" 日本語 "[0 ..1] ' – Shepmaster

+1

Forse Steve Klabnik, che ha scritto la risposta accettata, dovrebbe aggiornare il suo libro presente sul sito web di Rust perché mostra questo metodo esatto (https://doc.rust-lang.org/book/second-edition/ch04 -03-slices.html # stringa-slices). – FeFiFoFu

+0

Questo è brevemente trattato in quel capitolo del libro ("*' world' sarebbe una slice che contiene un puntatore ** al sesto byte ** di 's' e un valore di lunghezza di 5 *", enfasi mia) e in [maggiori dettagli in seguito] (https://doc.rust-lang.org/book/second-edition/ch08-02-strings.html#bytes-and-scalar-values-and-grapheme-clusters-oh- mio). – Shepmaster

0

ho scritto una funzione che restituisce la testa di un &str e il resto:

fn car_cdr(s: &str) -> (&str, &str) { 
    for i in 1..5 { 
     let r = s.get(0..i); 
     match r { 
      Some(x) => return (x, &s[i..]), 
      None =>(), 
     } 
    } 

    (&s[0..0], s) 
} 

usare in questo modo:

let (first_char, remainder) = car_cdr("test"); 
println!("first char: {}\nremainder: {}", first_char, remainder); 

L'output è simile:

first char: t 
remainder: est 

Funziona f ine con caratteri che hanno più di 1 byte.

+0

Sembra [come questo sarebbe più semplice] (https://play.rust-lang.org/?gist=c1a86a9de2b277ce571e5186eae85b7c&version=stable). – Shepmaster

+0

Shepmaster - la tua versione è davvero più semplice. Ma sono preoccupato per la funzione chars() - mi sembra che analizzi l'intera stringa e la analizzi in un vettore o qualcosa, mentre il mio codice guarda solo i primi 4 caratteri della stringa, al massimo. Ma forse sto fraintendendo come funziona chars()? – Sean

+0

Scusa, intendevo dire "primi 4 byte" non "primi 4 caratteri" – Sean

Problemi correlati