Converter uma String para int em Rust?

186

Nota: esta pergunta contém código pré-1.0 obsoleto! A resposta está correta, no entanto.

Para converter um strpara um intem Rust, eu posso fazer isso:

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

A única maneira de saber como converter um Stringpara um inté obter uma fatia e usá from_str-la da seguinte maneira:

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

Existe uma maneira de converter diretamente um Stringpara um int?

mtahmed
fonte
1
Consulte também: stackoverflow.com/q/32381414/500207 para não decimal (ou seja, hex).
Ahmed Fasih
2
Um tanto óbvio, mas uma observação para quem encontra essa pergunta bem depois de 2014 e se pergunta por que o from_str não está no escopo, não está no prelúdio. use std::str::FromStr;corrige isso. Mais sobre from_str, se desejar. doc.rust-lang.org/std/str/trait.FromStr.html#tymethod.from_str
7l-l04

Respostas:

259

Você pode converter diretamente para um int usando o str::parse::<T>()método .

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

Você pode especificar o tipo para analisar com o operador turboish ( ::<>) como mostrado acima ou através da anotação explícita do tipo:

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

Conforme mencionado nos comentários, parse()retorna a Result. Este resultado será um Errse a sequência não puder ser analisada como o tipo especificado (por exemplo, a sequência "peter"não pode ser analisada como i32).

John Vrbanac
fonte
35
Observe que parseretorna aResult , então você precisa lidar com isso adequadamente para obter um tipo integral real.
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>retorna a Result<u32, core::num::ParseIntError>e Result::unwrap"Desempacota um resultado, produzindo o conteúdo de um Ok[ou] pânico se o valor for um Err, com uma mensagem de pânico fornecida pelo Errvalor do".

str::parseé uma função genérica , daí o tipo entre colchetes angulares.

Jared Beck
fonte
9
Se você especificar o tipo da variável ( let my_u8: u8), não precisará do valor entre colchetes angulares. Observe também que o estilo Rust predominante indica que :deve ficar no lado esquerdo.
Shepmaster
5
Especificamente, eu quis dizerlet my_u32: u32 = "42".parse().unwrap()
Shepmaster
9

Se você obtiver sua corda stdin().read_line, precisará cortá-la primeiro.

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

Com uma noite recente, você pode fazer o seguinte:

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

O que está acontecendo aqui é que Stringagora pode ser desreferenciado para a str. No entanto, a função quer um &str, então temos que pedir emprestado novamente. Para referência, acredito que esse padrão específico ( &*) é chamado de "empréstimo cruzado".

DK.
fonte
Ok, eu não estou nas noites, mas vou aceitá-lo como resposta, já que realmente tentei desreferenciar um Stringem um ponto e esperei que funcionasse.
mtahmed
2
Como alternativa, você pode expressar my_sttring.as_slice()como my_string[](atualmente slicing_syntaxé fechado por recurso, mas provavelmente alguma forma dele terminaria no idioma).
tempestadept
1

Você pode usar o método FromStrda característica from_str, que é implementado para i32:

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

Bem não. Por que deveria haver? Apenas descarte a corda se não precisar mais dela.

&stré mais útil do que Stringquando você precisa ler apenas uma sequência, porque é apenas uma visualização da parte original dos dados, não do proprietário. Você pode Stringdistribuí- lo com mais facilidade e é copiável, portanto não é consumido pelos métodos invocados. Nesse sentido, é mais geral: se você tiver um String, poderá passá-lo para onde &stré esperado, mas, se tiver &str, só poderá passá-lo para funções esperadas Stringse fizer uma nova alocação.

Você pode encontrar mais informações sobre as diferenças entre esses dois e quando usá-los no guia oficial de strings .

Vladimir Matveev
fonte
Bem, uma razão óbvia para o porquê "deveria haver", na minha opinião, é que eu não precisaria fazer .as_slice()toda vez que preciso fazer from_strem uma String. Argumentos de linha de comando, por exemplo, é um lugar onde eu preciso fazer from_strem todos os argumentos para interpretá-los como ints etc.
mtahmed
as_slice()é apenas um aspecto menor do manuseio de strings. Por exemplo, você pode usar a sintaxe de fatia ( s[]) ou explorar a Derefcoerção ( &*s). Existe até uma proposta que permitiria escrever apenas &s.
precisa
Ooooh! O que &sfaria por uma string? Daria uma strvolta? Você poderia me indicar a proposta?
mtahmed
1
Primeiro de tudo, strnão é com o que você está trabalhando; é &str. Eles são diferentes (mas relacionados). O primeiro é um tipo de tamanho dinâmico que você quase nunca usaria diretamente, enquanto o último é uma fatia de corda que é um ponteiro gordo. A proposta é chamada de deref coercions ; permitiria coagir de &Tpara &Use T: Deref<U>. Desde String: Deref<str>já, você será capaz de obter &stra partir Stringcom apenas &. Ainda está em discussão, mas duvido que isso aconteça antes da versão 1.0 - resta muito pouco tempo.
precisa
-1

Então, basicamente, você deseja converter uma String em um inteiro inteiro! Aqui está o que eu mais uso e isso também é mencionado na documentação oficial.

fn main() {

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

}

Isso funciona para String e & str Espero que isso ajude também.

Taimoor
fonte