Chuyển đổi một chuỗi thành int trong Rust?


186

Lưu ý: câu hỏi này chứa mã pre-1.0 không dùng nữa! Câu trả lời là chính xác, mặc dù.

Để chuyển đổi strthành một inttrong Rust, tôi có thể làm điều này:

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

Cách duy nhất tôi biết làm thế nào để chuyển đổi một Stringthành một intlà lấy một lát của nó và sau đó sử dụng from_strnó như vậy:

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

Có cách nào để chuyển đổi trực tiếp Stringthành một int?


1
Xem thêm: stackoverflow.com/q / 32141414/500207 để không thập phân (tức là hex).
Ahmed Fasih

2
Hơi rõ ràng, nhưng một lưu ý cho bất cứ ai tìm thấy câu hỏi này tốt sau năm 2014, và tự hỏi tại sao from_str không nằm trong phạm vi, nó không nằm trong khúc dạo đầu. use std::str::FromStr;sửa lỗi đó Thêm về from_str nếu bạn muốn. doc.rust-lang.org/std/str/trait.FromStr.html#tymethod.from_str
-l04

Câu trả lời:


259

Bạn có thể trực tiếp chuyển đổi sang một int bằng str::parse::<T>()phương thức này .

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

Bạn có thể chỉ định loại để phân tích cú pháp với toán tử phản lực ( ::<>) như được hiển thị ở trên hoặc thông qua chú thích loại rõ ràng:

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

Như đã đề cập trong các ý kiến, parse()trả về a Result. Kết quả này sẽ là Errnếu chuỗi không thể được phân tích cú pháp như loại được chỉ định (ví dụ: chuỗi "peter"không thể được phân tích cú pháp dưới dạng i32).


35
Lưu ý rằng parsetrả về aResult , vì vậy bạn cần xử lý một cách thích hợp để có được một loại tích phân thực tế.
Người quản lý

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>trả về a Result<u32, core::num::ParseIntError>Result::unwrap"Bỏ kết quả, mang lại nội dung của Ok[hoặc] hoảng loạn nếu giá trị là một Err, với thông điệp hoảng loạn được cung cấp bởi Errgiá trị của".

str::parselà một hàm chung , do đó loại trong ngoặc vuông.


9
Nếu bạn chỉ định loại biến ( let my_u8: u8), thì bạn không cần giá trị trong ngoặc vuông. Cũng lưu ý rằng kiểu Rust thịnh hành chỉ ra rằng :nên bám vào phía bên trái.
Người quản lý

5
Cụ thể, ý tôi làlet my_u32: u32 = "42".parse().unwrap()
Người quản lý

9

Nếu bạn nhận được chuỗi của bạn từ stdin().read_line, bạn phải cắt nó trước.

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

6

Với một đêm gần đây, bạn có thể làm điều này:

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

Điều đang xảy ra ở đây là Stringbây giờ có thể được quy định thành một str. Tuy nhiên, hàm muốn một &str, vì vậy chúng ta phải mượn lại. Để tham khảo, tôi tin rằng mẫu đặc biệt này ( &*) được gọi là "vay chéo".


Được rồi, tôi không phải là người thích ngủ đêm nhưng tôi sẽ chấp nhận nó như một câu trả lời vì tôi thực sự đã cố gắng để quy định lại Stringtại một thời điểm và hy vọng nó sẽ hoạt động.
mtahmed

2
Ngoài ra, bạn có thể diễn đạt my_sttring.as_slice()như my_string[](hiện tại slicing_syntaxlà tính năng có kiểm soát, nhưng hầu hết có thể một số dạng của nó sẽ kết thúc bằng ngôn ngữ).
tempestadept

1

Bạn có thể sử dụng phương pháp FromStrcủa đặc điểm from_str, được triển khai cho i32:

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

0

Ồ không. Tại sao nên có? Chỉ cần loại bỏ chuỗi nếu bạn không cần nó nữa.

&strhữu ích hơn so với Stringkhi bạn chỉ cần đọc một chuỗi, bởi vì nó chỉ là một khung nhìn vào phần dữ liệu gốc chứ không phải chủ sở hữu của nó. Bạn có thể vượt qua nó dễ dàng hơn String, và nó có thể sao chép, vì vậy nó không bị tiêu thụ bởi các phương thức được gọi. Về vấn đề này thì tổng quát hơn: nếu bạn có a String, bạn có thể chuyển nó đến nơi &strdự kiến, nhưng nếu bạn có &str, bạn chỉ có thể chuyển nó cho các chức năng mong đợi Stringnếu bạn thực hiện phân bổ mới.

Bạn có thể tìm hiểu thêm về sự khác biệt giữa hai điều này và khi nào nên sử dụng chúng trong hướng dẫn chuỗi chính thức .


Chà, một lý do rõ ràng cho lý do tại sao "nên có", theo ý kiến ​​của tôi, là tôi sẽ không phải làm .as_slice()mỗi khi tôi cần làm from_strtrên Chuỗi. Ví dụ, các đối số dòng lệnh là một nơi mà tôi cần phải thực hiện from_strtrên tất cả các đối số để diễn giải chúng là ints, v.v.
mtahmed

as_slice()chỉ là một khía cạnh nhỏ của xử lý chuỗi. Ví dụ: bạn có thể sử dụng cú pháp cắt ( s[]) hoặc khai thác Derefcưỡng chế ( &*s). Thậm chí còn có một đề xuất cho phép viết chỉ &s.
Vladimir Matveev

Ôi trời! Điều gì sẽ &slàm cho một chuỗi? Nó sẽ trả strlại? Bạn có thể chỉ cho tôi đề xuất?
mtahmed

1
Trước hết, strkhông phải là những gì bạn đang làm việc với; nó là &str. Chúng khác nhau (nhưng có liên quan). Loại trước là loại có kích thước động mà bạn gần như không bao giờ sử dụng trực tiếp, trong khi loại thứ hai là một lát cắt chuỗi là một con trỏ béo. Đề xuất này được gọi là cưỡng chế deref ; nó sẽ cho phép để ép buộc từ &Tđể &Unếu T: Deref<U>. Kể từ khi String: Deref<str>đã có, bạn sẽ có thể để có được &strtừ Stringchỉ với &. Nó vẫn còn trong cuộc thảo luận nhưng tôi nghi ngờ điều đó sẽ xảy ra trước 1.0 - còn quá ít thời gian.
Vladimir Matveev

-1

Vì vậy, về cơ bản, bạn muốn chuyển đổi một Chuỗi thành một số nguyên ngay! đây là những gì tôi chủ yếu sử dụng và nó cũng được đề cập trong tài liệu chính thức ..

fn main() {

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

}

Điều này hoạt động cho cả String và & str Hy vọng điều này cũng sẽ giúp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.