TL; DR: Bir yerine kullanabilir &str
, &[T]
ya da &T
daha genel kod için izin vermek.
A String
veya a kullanmanın ana nedenlerinden biri Vec
, kapasiteyi artırmaya veya azaltmaya izin vermeleridir. Ancak, değişmez bir referansı kabul ettiğinizde, bu ilginç yöntemlerin hiçbirini Vec
veya üzerinde kullanamazsınız String
.
Bir Kabul &String
, &Vec
ya &Box
da gerektirir işlevi çağırabilir önce öbek üzerinde tahsis edilecek argüman. A'nın kabul edilmesi &str
, bir dizgeye (program verilerine kaydedilen) izin verir ve bir yığın tahsisli dizi veya değişkene izin verir &[T]
veya kabul eder &T
. Gereksiz ayırma bir performans kaybıdır. Bu genellikle, bu yöntemleri bir test veya yöntemde çağırmaya çalıştığınızda hemen ortaya çıkar main
:
awesome_greeting(&String::from("Anna"));
total_price(&vec![42, 13, 1337])
is_even(&Box::new(42))
Başka bir performans dikkate yani &String
, &Vec
ve &Box
sen KQUEUE sahip olarak dolaylama gereksiz tabaka oluşturulur &String
bir almak String
ve daha sonra en sonuna kadar ikinci bir dereference gerçekleştirmek &str
.
Bunun yerine, bir dize dilimi ( &str
), bir dilim ( &[T]
) veya sadece bir referansı ( &T
) kabul etmelisiniz . A &String
, &Vec<T>
veya &Box<T>
otomatik olarak sırasıyla a &str
, &[T]
veya &T
'ye zorlanacaktır.
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
}
Artık bu yöntemleri daha geniş bir tür kümesiyle çağırabilirsiniz. Örneğin, awesome_greeting
bir dize değişmezi ( "Anna"
) veya tahsis edilmiş olarak çağrılabilir String
. total_price
bir dizi ( &[1, 2, 3]
) veya ayrılmış bir referansla çağrılabilir Vec
.
Eklemek veya öğeleri kaldırmak istiyorsanız String
ya Vec<T>
, bir alabilir değişken referans ( &mut String
ya &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);
}
Özellikle dilimler için bir &mut [T]
veya &mut str
. Bu, dilim içindeki belirli bir değeri değiştirmenize izin verir, ancak dilim içindeki öğelerin sayısını değiştiremezsiniz (bu, dizeler için çok kısıtlı olduğu anlamına gelir):
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
Daha geneldir (olduğu gibi: daha az kısıtlama getirir), sınırlı yetenekler olmadan"? Ayrıca: 3. nokta genellikle sanırım o kadar da önemli değil. GenellikleVec
s veString
s'ler yığın üzerinde ve hatta mevcut yığın çerçevesine yakın bir yerde yaşarlar. Yığın genellikle sıcaktır ve referans bir CPU önbelleğinden sunulacaktır.