แปลง String เป็น int ใน Rust หรือไม่?


187

หมายเหตุ: คำถามนี้มีรหัส pre-1.0 ที่เลิกใช้แล้ว! แม้ว่าคำตอบนั้นถูกต้องแล้ว

หากต้องการแปลง a strเป็นintin in Rust ฉันทำได้ดังนี้:

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

วิธีเดียวที่ฉันรู้วิธีที่จะแปลงStringไปสู่การintที่จะได้รับส่วนแบ่งของมันแล้วใช้from_strมันเพื่อต้องการ:

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

มีวิธีการแปลงโดยตรงที่Stringไปยังint?


1
ดูเพิ่มเติมที่: stackoverflow.com/q/32381414/500207สำหรับ non-decimal (เช่น hex)
Ahmed Fasih

2
ค่อนข้างชัดเจน แต่มีข้อความสำหรับทุกคนที่พบคำถามนี้ได้ดีหลังจากปี 2014 และสงสัยว่าเหตุใด from_str ไม่อยู่ในขอบเขตมันไม่ได้อยู่ในบทนำ use std::str::FromStr;แก้ไขที่ เพิ่มเติมจาก from_str หากคุณต้องการ doc.rust-lang.org/std/str/trait.FromStr.html#tymethod.from_str
-l04

คำตอบ:


261

คุณโดยตรงสามารถแปลงเป็น int โดยใช้วิธีการstr::parse::<T>()

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

คุณสามารถระบุประเภทที่จะวิเคราะห์ด้วยตัวดำเนินการ turbofish ( ::<>) ดังที่แสดงด้านบนหรือผ่านคำอธิบายประกอบประเภทที่ชัดเจน:

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

ตามที่ระบุไว้ในความคิดเห็นที่ส่งกลับparse() Resultผลลัพธ์นี้จะเป็นErrถ้าสตริงไม่สามารถแยกวิเคราะห์ตามประเภทที่ระบุ (ตัวอย่างเช่นสตริง"peter"ไม่สามารถแยกวิเคราะห์เป็นi32)


35
โปรดทราบว่าparseส่งคืน aResultดังนั้นคุณต้องจัดการกับสิ่งนั้นอย่างเหมาะสมเพื่อไปยังประเภทอินทิกรัลจริง
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>ส่งคืน a Result<u32, core::num::ParseIntError>และResult::unwrap"Unwraps ผลลัพธ์ให้ผลลัพธ์เนื้อหาของOk[หรือ] panics หากค่าคือErra พร้อมกับข้อความ panic ที่ระบุโดยค่าErr's

str::parseเป็นฟังก์ชั่นทั่วไปดังนั้นประเภทในวงเล็บมุม


9
หากคุณระบุประเภทของตัวแปร ( let my_u8: u8) คุณไม่จำเป็นต้องใช้ค่าในวงเล็บเหลี่ยม นอกจากนี้โปรดทราบว่ารูปแบบสนิมที่เกิดขึ้นบ่งบอกว่า:ควรติดด้านซ้าย
Shepmaster

5
โดยเฉพาะฉันหมายถึงlet my_u32: u32 = "42".parse().unwrap()
Shepmaster

9

หากคุณได้รับสายจากstdin().read_lineคุณต้องตัดมันก่อน

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

6

เมื่อคืนนี้คุณสามารถทำสิ่งนี้:

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

สิ่งที่เกิดขึ้นที่นี่เป็นที่Stringขณะนี้สามารถ dereferenced strเป็น อย่างไรก็ตามฟังก์ชั่นต้องการ&strและเราต้องยืมอีกครั้ง สำหรับการอ้างอิงฉันเชื่อว่ารูปแบบเฉพาะนี้ ( &*) เรียกว่า "การกู้ยืมข้าม"


โอเคฉันไม่ได้อยู่ใน nightlies แต่ฉันจะยอมรับว่ามันเป็นคำตอบเนื่องจากฉันพยายามที่จะตรวจสอบข้อเท็จจริงStringในจุดหนึ่งและหวังว่ามันจะทำงาน
mtahmed

2
หรือคุณสามารถแสดงmy_sttring.as_slice()เป็นmy_string[](ปัจจุบันslicing_syntaxมีการกำหนดคุณสมบัติ แต่ส่วนใหญ่อาจเป็นรูปแบบบางอย่างที่จะสิ้นสุดในภาษา)
tempestadept

2

คุณสามารถใช้วิธีการFromStrของคุณลักษณะfrom_strซึ่งมีการใช้งานสำหรับi32:

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

0

ไม่เลย ทำไมต้องมี? เพียงแค่ทิ้งสตริงถ้าคุณไม่ต้องการมันอีกต่อไป

&strมีประโยชน์มากกว่าStringเมื่อคุณจำเป็นต้องอ่านสตริงเท่านั้นเพราะเป็นเพียงการดูข้อมูลชิ้นส่วนดั้งเดิมไม่ใช่เจ้าของ คุณสามารถส่งผ่านได้ง่ายกว่าStringและสามารถคัดลอกได้ดังนั้นจึงไม่ใช้วิธีที่เรียกใช้ ในเรื่องนี้มันเป็นเรื่องทั่วไปมากขึ้น: ถ้าคุณมีStringคุณสามารถส่งมันไปยังที่ที่&strคาดหวัง แต่ถ้าคุณมี&strคุณสามารถส่งผ่านไปยังฟังก์ชั่นที่คาดหวังStringหากคุณทำการจัดสรรใหม่

คุณสามารถค้นหาข้อมูลเพิ่มเติมเกี่ยวกับความแตกต่างระหว่างสองคนนี้และเมื่อจะใช้พวกเขาในคู่มือสตริงอย่างเป็นทางการ


ด้วยเหตุผลที่ชัดเจนว่าทำไม "ควรมี" ในความคิดของฉันก็คือฉันไม่ต้องทำ.as_slice()ทุกครั้งที่ฉันต้องทำfrom_strกับสตริง อาร์กิวเมนต์บรรทัดคำสั่งตัวอย่างเช่นเป็นหนึ่งในสถานที่ที่ผมต้องทำfrom_strใน args ทั้งหมดที่จะแปลความหมายได้เป็นintเป็นต้น
mtahmed

as_slice()เป็นเพียงส่วนน้อยของการจัดการสตริง ตัวอย่างเช่นคุณสามารถใช้การแบ่งส่วนข้อมูล ( s[]) หรือใช้ประโยชน์จากการDerefข่มขู่ ( &*s) &sแม้จะมีข้อเสนอซึ่งจะช่วยให้การเขียนเพียง
Vladimir Matveev

Ooooh! สิ่งที่จะ&sทำสำหรับสตริง? มันจะให้strกลับมา? คุณช่วยชี้ข้อเสนอให้ฉันได้ไหม
mtahmed

1
ประการแรกstrไม่ใช่สิ่งที่คุณทำงานด้วย &strมันเป็น พวกเขาแตกต่างกัน (แต่เกี่ยวข้องกัน) รูปแบบก่อนหน้าเป็นรูปแบบที่มีขนาดแบบไดนามิกซึ่งคุณแทบจะไม่เคยใช้โดยตรงในขณะที่รูปแบบหลังเป็นชิ้นส่วนของสตริงซึ่งเป็นตัวชี้ไขมัน ข้อเสนอนี้เรียกว่าderef coercions ; มันจะช่วยให้การบีบบังคับจาก&Tไปถ้า&U T: Deref<U>ตั้งแต่String: Deref<str>อยู่แล้วคุณจะสามารถที่จะได้รับ&strจากที่มีเพียงString &ยังอยู่ในระหว่างการสนทนา แต่ฉันสงสัยว่ามันจะเกิดขึ้นก่อน 1.0 - เหลือเวลาน้อยเกินไป
Vladimir Matveev

-1

โดยพื้นฐานแล้วคุณต้องการแปลงสตริงให้เป็นจำนวนเต็มอย่างถูกต้อง! นี่คือสิ่งที่ฉันใช้เป็นส่วนใหญ่และที่กล่าวถึงในเอกสารอย่างเป็นทางการ ..

fn main() {

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

}

สิ่งนี้ใช้ได้กับทั้ง String และ & str หวังว่าจะช่วยได้เช่นกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.