Konversi string ke int di Rust?

186

Catatan: pertanyaan ini mengandung kode pra-1.0 yang sudah usang! Jawabannya benar.

Untuk mengonversi a strmenjadi intdalam Rust, saya dapat melakukan ini:

let my_int = from_str::<int>(my_str);

Satu-satunya cara saya tahu cara mengonversikan Stringke intadalah dengan mendapatkan sepotong dan kemudian menggunakannya from_strseperti:

let my_int = from_str::<int>(my_string.as_slice());

Apakah ada cara untuk secara langsung mengkonversi a Stringke int?

mtahmed
sumber
1
Lihat juga: stackoverflow.com/q/32381414/500207 untuk non-desimal (yaitu, hex).
Ahmed Fasih
2
Agak jelas, tetapi catatan bagi siapa pun yang menemukan pertanyaan ini setelah 2014, dan bertanya-tanya mengapa from_str tidak dalam ruang lingkup, itu tidak ada di awal. use std::str::FromStr;memperbaikinya. Lebih lanjut tentang from_str jika Anda mau. doc.rust-lang.org/std/str/trait.FromStr.html#tymethod.from_str
7l-l04

Jawaban:

259

Anda dapat langsung mengonversi ke int menggunakan str::parse::<T>()metode ini .

let my_string = "27".to_string();  // `parse()` works with `&str` and `String`!
let my_int = my_string.parse::<i32>().unwrap();

Anda dapat menentukan jenis yang akan diuraikan dengan operator turbofish ( ::<>) seperti yang ditunjukkan di atas atau melalui anotasi jenis eksplisit:

let my_int: i32 = my_string.parse().unwrap();

Seperti yang disebutkan dalam komentar, parse()mengembalikan a Result. Hasil ini akan menjadi Errjika string tidak dapat diuraikan sebagai tipe yang ditentukan (misalnya, string "peter"tidak dapat diuraikan sebagai i32).

John Vrbanac
sumber
35
Perhatikan bahwa parsemengembalikan aResult , jadi Anda harus menghadapinya dengan tepat untuk mendapatkan tipe integral yang sebenarnya.
Shepmaster
54
let my_u8: u8 = "42".parse::<u8>().unwrap();
let my_u32: u32 = "42".parse::<u32>().unwrap();

// or, to be safe, match the `Err`
match "foobar".parse::<i32>() {
  Ok(n) => do_something_with(n),
  Err(e) => weep_and_moan(),
}

str::parse::<u32>mengembalikan a Result<u32, core::num::ParseIntError>dan Result::unwrap"Membongkar hasil, menghasilkan konten Ok[atau] panik jika nilainya adalah Err, dengan pesan panik yang disediakan oleh nilai Err's."

str::parseadalah fungsi generik , maka jenis kurung sudut.

Jared Beck
sumber
9
Jika Anda menentukan jenis variabel ( let my_u8: u8), maka Anda tidak perlu nilai dalam kurung sudut. Perhatikan juga bahwa gaya Karat yang berlaku menunjukkan bahwa :harus menempel di sisi kiri.
Shepmaster
5
Secara khusus, maksud sayalet my_u32: u32 = "42".parse().unwrap()
Shepmaster
9

Jika Anda mendapatkan string dari stdin().read_line, Anda harus memotongnya terlebih dahulu.

let my_num: i32 = my_num.trim().parse()
   .expect("please give me correct string number!");
Ade Yahya
sumber
6

Dengan malam baru-baru ini, Anda dapat melakukan ini:

let my_int = from_str::<int>(&*my_string);

Apa yang terjadi di sini adalah yang Stringsekarang dapat direferensikan menjadi str. Namun, fungsi menginginkan &str, jadi kita harus meminjam lagi. Untuk referensi, saya percaya pola khusus ini ( &*) disebut "pinjaman silang".

DK.
sumber
Oke saya tidak di nightlies tetapi saya akan menerimanya sebagai jawaban karena saya benar-benar mencoba dereference Stringpada satu titik dan berharap itu akan berhasil.
mtahmed
2
Atau, Anda dapat mengekspresikan my_sttring.as_slice()sebagai my_string[](saat ini slicing_syntaxadalah fitur-gated, tetapi kemungkinan besar beberapa bentuk itu akan berakhir dalam bahasa).
tempestadept
1

Anda dapat menggunakan metode FromStrsifat from_str, yang diterapkan untuk i32:

let my_num = i32::from_str("9").unwrap_or(0);
Karthik Cherukuri
sumber
0

Ya tidak. Kenapa harus ada? Buang saja string jika Anda tidak membutuhkannya lagi.

&strlebih berguna daripada Stringsaat Anda hanya perlu membaca string, karena itu hanya tampilan ke bagian data asli, bukan pemiliknya. Anda dapat menyebarkannya lebih mudah daripada String, dan dapat disalin, sehingga tidak dikonsumsi oleh metode yang dipanggil. Dalam hal ini lebih umum: jika Anda memiliki String, Anda dapat meneruskannya ke tempat yang &strdiharapkan, tetapi jika Anda memilikinya &str, Anda hanya dapat meneruskannya ke fungsi yang diharapkan Stringjika Anda membuat alokasi baru.

Anda dapat menemukan lebih banyak tentang perbedaan antara keduanya dan kapan menggunakannya dalam panduan string resmi .

Vladimir Matveev
sumber
Nah, alasan yang jelas mengapa "harus ada", menurut saya, adalah bahwa saya tidak harus melakukan .as_slice()setiap kali saya harus melakukan from_strpada String. Argumen baris perintah, misalnya, adalah satu tempat di mana saya perlu melakukan from_strpada semua argumen untuk menafsirkannya sebagai intdll.
mtahmed
as_slice()hanyalah aspek minor dari penanganan string. Misalnya, Anda bisa menggunakan slicing syntax ( s[]) atau exploit Derefcoersion ( &*s). Bahkan ada proposal yang akan memungkinkan untuk menulis adil &s.
Vladimir Matveev
Ooooh! Apa yang akan &sdilakukan untuk sebuah string? Apakah itu akan memberi strbalasan? Bisakah Anda mengarahkan saya ke proposal?
mtahmed
1
Pertama-tama, strbukan apa yang Anda kerjakan; itu &str. Mereka berbeda (tetapi terkait). Yang pertama adalah tipe berukuran dinamis yang hampir tidak akan pernah Anda gunakan secara langsung, sedangkan yang terakhir adalah string slice yang merupakan penunjuk gemuk. Proposal ini disebut paksaan deref ; itu akan memungkinkan untuk memaksa dari &Tke &Ujika T: Deref<U>. Karena String: Deref<str>sudah, Anda akan dapat memperoleh&str dari Stringdengan adil &. Masih dalam diskusi tetapi saya ragu itu akan terjadi sebelum 1.0 - masih ada sedikit waktu yang tersisa.
Vladimir Matveev
-1

Jadi pada dasarnya Anda ingin mengubah String menjadi Integer kan! inilah yang paling sering saya gunakan dan itu juga disebutkan dalam dokumentasi resmi ..

fn main() {

    let char = "23";
    let char : i32 = char.trim().parse().unwrap();
    println!("{}", char + 1);

}

Ini berfungsi untuk String dan & str. Harapan ini juga akan membantu.

Taimoor
sumber