TL; DR: Em vez disso &str, pode-se usar &[T]ou &Tpermitir código mais genérico.
Um dos principais motivos para usar a Stringou a Vecé porque eles permitem aumentar ou diminuir a capacidade. No entanto, quando você aceita uma referência imutável, não pode usar nenhum desses métodos interessantes no Vecor String.
Aceitar a &String, &Vecou &Boxtambém exige que o argumento seja alocado no heap antes que você possa chamar a função. Aceitar a &strpermite um literal de cadeia de caracteres (salvo nos dados do programa) e aceitar uma &[T]ou &Tpermite uma matriz ou variável alocada por pilha. Alocação desnecessária é uma perda de desempenho. Isso geralmente é exposto imediatamente quando você tenta chamar esses métodos em um teste ou mainmétodo:
awesome_greeting(&String::from("Anna"));
total_price(&vec![42, 13, 1337])
is_even(&Box::new(42))
Outra consideração de desempenho é que &String, &Vece &Boxintroduza uma camada desnecessária de indireção, pois você deve desreferenciar o &Stringpara obter um Stringe executar uma segunda desreferência para terminar &str.
Em vez disso, você deve aceitar uma fatia de string ( &str), uma fatia ( &[T]) ou apenas uma referência ( &T). A &String, &Vec<T>ou &Box<T>será automaticamente coagido a a &str, &[T]ou &T, respectivamente.
fn awesome_greeting(name: &str) {
println!("Wow, you are awesome, {}!", name);
}
fn total_price(prices: &[i32]) -> i32 {
prices.iter().sum()
}
fn is_even(value: &i32) -> bool {
*value % 2 == 0
}
Agora você pode chamar esses métodos com um conjunto mais amplo de tipos. Por exemplo, awesome_greetingpode ser chamado com uma string literal ( "Anna") ou alocada String. total_pricepode ser chamado com uma referência a uma matriz ( &[1, 2, 3]) ou alocada Vec.
Se você deseja adicionar ou remover itens do Stringou Vec<T>, pode usar uma referência mutável ( &mut Stringou &mut Vec<T>):
fn add_greeting_target(greeting: &mut String) {
greeting.push_str("world!");
}
fn add_candy_prices(prices: &mut Vec<i32>) {
prices.push(5);
prices.push(25);
}
Especificamente para fatias, você também pode aceitar um &mut [T]ou &mut str. Isso permite que você modifique um valor específico dentro da fatia, mas não é possível alterar o número de itens dentro da fatia (o que significa que é muito restrito para cadeias):
fn reset_first_price(prices: &mut [i32]) {
prices[0] = 0;
}
fn lowercase_first_ascii_character(s: &mut str) {
if let Some(f) = s.get_mut(0..1) {
f.make_ascii_lowercase();
}
}
&stré mais geral (como: impõe menos restrições) sem capacidade reduzida"? Além disso: o ponto 3 geralmente não é tão importante assim. Normalmente,Vecs eStrings ficam na pilha e geralmente até em algum lugar próximo ao quadro atual da pilha. A pilha geralmente está quente e a desreferência será servida a partir de um cache da CPU.