2016-09-09 19 views
7

Rdza ma FromStr, jednak z tego co widzę, przyjmuje tylko tekst Unicode. Czy istnieje odpowiednik tego dla macierzy [u8]?Czy Rust zapewnia sposób analizowania liczb całkowitych bezpośrednio z danych ASCII w tablicach bajtowych (u8)?

Przez "parsowanie" rozumiem, że przyjmuję znaki ASCII i zwracam liczbę całkowitą, np. C's atoi.

Albo muszę albo ...

  • Konwersja tablicy u8 do łańcucha, potem zadzwonić FromStr.
  • Zadzwoń pod numer atoi biblioteki libc.
  • Napisz atoi w Rust.

W prawie wszystkich przypadkach, pierwsza opcja jest uzasadnione, jednak istnieją przypadki, w których pliki może być bardzo duża, bez określonej kodowania ... albo zawierają mieszane binarne i tekstowe, gdzie jej najbardziej proste do odczytania liczb całkowitych jako bajty.

+3

Jeśli mają mieszane binarny i tekstowy w formacie niestandardowym, być może należy przeanalizować cały plik * * Korzystanie parser takich jak [nom] (https://github.com/Geal/nom). – kennytm

+2

Co to ma znaczenie, jeśli plik jest duży? Po prostu konwertuj, aby utworzyć wycinek, który znasz, zawierający liczbę: 'i32 :: from_str (str :: from_utf8 (& data [a..b]). Unwrap()). Unwrap()'. IIRC, czyli zero-kopia. – rodrigo

+0

Plik jest duży to tylko uwaga, że ​​może zawierać GB danych, więc bardziej optymalna metoda, która nie korzysta z dodatkowej konwersji i przechowywania pośredniego, może być preferowana w niektórych przypadkach, nawet z 'from_utf8', spodziewam się, że kod ścieżka sprawdza wiele znaków wielobajtowych? jeśli wiemy, że dane są tablicą cyfr, nie ma problemu z napisaniem 'atoi', co prawda nie jest to typowy przypadek użycia. – ideasman42

Odpowiedz

6

Nie, biblioteka standardowa nie ma takiej funkcji, ale jej nie potrzebuje.

Jak podano w komentarzach, surowe bajty mogą być konwertowane do &str poprzez:

  1. str::from_utf8
  2. str::from_utf8_unchecked

Żadna z nich wykonać dodatkowy przydział. Pierwsza z nich zapewnia poprawność bajtów UTF-8, druga nie. Wszyscy powinni używać sprawdzanego formularza do czasu, gdy profilowanie udowodni, że jest to wąskie gardło, a następnie użyj niezaznaczonego formularza, gdy okaże się, że jest to bezpieczne.

Jeśli bajtów głębiej w danych muszą być przetwarzane, A plaster surowych bajtów można otrzymać przed konwersją:

use std::str; 

fn main() { 
    let raw_data = b"123132"; 

    let the_bytes = &raw_data[1..4]; 
    let the_string = str::from_utf8(the_bytes).expect("not UTF-8"); 
    let the_number: u64 = the_string.parse().expect("not a number"); 

    assert_eq!(the_number, 231); 
} 

jak w inne kody te linie te można wyodrębnić w funkcji lub cecha pozwalająca na ponowne użycie. Jednak gdy ta ścieżka zostanie zastosowana, dobrze byłoby zajrzeć do jednego z wielu wspaniałych crates aimed at parsing. Jest to szczególnie ważne, jeśli oprócz danych tekstowych konieczne jest przetwarzanie danych binarnych.

1

Nie znam żadnego sposobu w standardowej bibliotece, ale może skrzynia atoi działa dla ciebie?

extern crate atoi; 
use atoi::atoi; 

let (number, digits) = atoi::<u32>(b"42 is the answer"); //returns (42,2) 

Można sprawdzić, czy drugi element krotki jest zerem, aby sprawdzić, czy plaster zaczyna się od cyfry.

let (number, digits) = atoi::<u32>(b"x"); //returns (0,0) 
let (number, digits) = atoi::<u32>(b"0"); //returns (0,1)