In Rust einen String in int konvertieren?

180

Hinweis: Diese Frage enthält veralteten Code vor 1.0! Die Antwort ist jedoch richtig.

Um ein strin ein intin Rust umzuwandeln , kann ich Folgendes tun:

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

Der einzige Weg, wie ich a Stringin ein konvertieren kann , intbesteht darin, ein Stück davon zu bekommen und es dann from_strwie folgt zu verwenden :

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

Gibt es eine Möglichkeit , um direkt eine umwandeln Stringzu ein int?

mtahmed
quelle
1
Siehe auch: stackoverflow.com/q/32381414/500207 für nicht dezimale (dh hexadezimale) Werte .
Ahmed Fasih
2
Etwas offensichtlich, aber ein Hinweis für alle, die diese Frage weit nach 2014 finden und sich fragen, warum from_str nicht im Geltungsbereich liegt, nicht im Vorspiel. use std::str::FromStr;behebt das. Mehr zu from_str, wenn Sie möchten. doc.rust-lang.org/std/str/trait.FromStr.html#tymethod.from_str
7l-l04

Antworten:

250

Mit der str::parse::<T>()Methode können Sie direkt in ein int konvertieren .

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

Sie können entweder den Typ angeben, auf den mit dem Turbofish-Operator ( ::<>) analysiert werden soll, wie oben gezeigt, oder über eine explizite Typanmerkung :

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

Wie in den Kommentaren erwähnt, wird parse()a zurückgegeben Result. Dieses Ergebnis ist ein Ergebnis, Errwenn die Zeichenfolge nicht als der angegebene Typ analysiert werden konnte (z. B. kann die Zeichenfolge "peter"nicht als analysiert werden i32).

John Vrbanac
quelle
35
Beachten Sie, dass parsea zurückgegebenResult wird. Sie müssen also entsprechend damit umgehen, um zu einem tatsächlichen Integraltyp zu gelangen.
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>gibt ein Result<u32, core::num::ParseIntError>und zurückResult::unwrap "Packt ein Ergebnis aus und liefert den Inhalt einer Ok[oder] Panik, wenn der Wert ein ist Err, mit einer Panikmeldung, die vom ErrWert des ' bereitgestellt wird ."

str::parseist eine generische Funktion , daher der Typ in spitzen Klammern.

Jared Beck
quelle
8
Wenn Sie den Typ der Variablen ( let my_u8: u8) angeben , benötigen Sie den Wert nicht in spitzen Klammern. Beachten Sie auch, dass der vorherrschende Roststil anzeigt, dass er :auf der linken Seite bleiben sollte.
Shepmaster
4
Konkret meinte ichlet my_u32: u32 = "42".parse().unwrap()
Shepmaster
9

Wenn Sie Ihre Saite erhalten stdin().read_line, müssen Sie sie zuerst kürzen.

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

Mit einem letzten Abend können Sie dies tun:

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

Was hier passiert ist, dass Stringjetzt in eine dereferenziert werden kann str. Die Funktion will jedoch eine &str, also müssen wir uns wieder ausleihen. Als Referenz glaube ich, dass dieses spezielle Muster ( &*) als "Cross-Borrowing" bezeichnet wird.

DK.
quelle
Okay, ich bin nicht auf Nightlies, aber ich werde es als Antwort akzeptieren, da ich tatsächlich versucht habe, eine Stringan einem Punkt zu dereferenzieren und hoffte, dass es funktionieren würde.
Mtahmed
2
Alternativ können Sie my_sttring.as_slice()als ausdrücken my_string[](derzeit slicing_syntaxist es funktionsgesteuert, aber höchstwahrscheinlich würde eine Form davon in der Sprache enden).
Tempestadept
1

Sie können die Methode des FromStrMerkmals from_strverwenden, die implementiert ist für i32:

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

Nun, nein. Warum sollte es geben? Verwerfen Sie die Zeichenfolge einfach, wenn Sie sie nicht mehr benötigen.

&strist nützlicher als Stringwenn Sie nur eine Zeichenfolge lesen müssen, da es sich nur um eine Ansicht der ursprünglichen Daten handelt, nicht um deren Eigentümer. Sie können es einfacher weitergeben als Stringund es ist kopierbar, sodass es nicht von den aufgerufenen Methoden verwendet wird. In dieser Hinsicht ist es allgemeiner: Wenn Sie ein haben String, können Sie es an die Stelle übergeben, an der ein &strerwartet wird. Wenn Sie dies haben &str, können Sie es nur an Funktionen übergeben, die erwarten, Stringdass Sie eine neue Zuordnung vornehmen.

Weitere Informationen zu den Unterschieden zwischen diesen beiden und deren Verwendung finden Sie im offiziellen String-Handbuch .

Vladimir Matveev
quelle
Nun, ein offensichtlicher Grund dafür, warum "es sollte", ist meiner Meinung nach, dass ich nicht .as_slice()jedes Mal tun müsste, wenn ich from_stran einem String arbeiten muss. Befehlszeilenargumente zum Beispiel sind eine Stelle, an der ich from_stralle Argumente int
bearbeiten muss
as_slice()ist nur ein kleiner Aspekt der Handhabung von Zeichenfolgen. Sie können beispielsweise die Slicing-Syntax ( s[]) verwenden oder DerefZwang ( &*s) ausnutzen . Es gibt sogar einen Vorschlag, der es erlauben würde, nur zu schreiben &s.
Vladimir Matveev
Ooooh! Was würde &sfür eine Saite tun? Würde es etwas strzurückgeben? Könnten Sie mich auf den Vorschlag hinweisen?
Mtahmed
1
Erstens strist es nicht das, womit Sie arbeiten; es ist &str. Sie sind unterschiedlich (aber verwandt). Ersteres ist ein Typ mit dynamischer Größe, den Sie fast nie direkt verwenden würden, während letzteres ein String-Slice ist, das ein fetter Zeiger ist. Der Vorschlag heißt Deref-Zwang ; es erlauben würde , von zu zwingen , &Tzu&U wenn T: Deref<U>. Da String: Deref<str>bereits, Sie erhalten können &straus Stringmit nur &. Es wird noch diskutiert, aber ich bezweifle, dass es vor 1.0 passieren wird - es bleibt zu wenig Zeit.
Vladimir Matveev
-1

Im Grunde möchten Sie also einen String in eine Ganzzahl umwandeln, richtig! Hier ist, was ich meistens benutze und das wird auch in der offiziellen Dokumentation erwähnt.

fn main() {

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

}

Dies funktioniert sowohl für String als auch für & str. Ich hoffe, dies wird auch helfen.

Taimoor
quelle