TL; DR:可以改爲使用&str
,&[T]
或&T
而不喪失通用性。
一個使用String
或Vec
的主要原因是因爲它們允許增加或減少容量。但是,如果您接受不可變引用,則不能在Vec
或String
上使用任何有趣的方法。
接受&String
,&Vec
或&Box
也需要分配,然後才能調用該方法。不必要的分配是性能損失。這通常是暴露時,馬上你嘗試調用在測試這些方法或main
方法:
awesome_greeting(&String::from("Anna"));
total_price(&vec![42, 13, 1337])
is_even(&Box::new(42))
另一個性能考慮是&String
,&Vec
和&Box
介紹一個不必要的間接層,因爲您已取消&String
以獲得String
,然後第二個解除引用最終在&str
。
相反,你應該接受串片(&str
),一個片(&[T]
),或只是一個參考&T
。 A &String
,&Vec<T>
或&Box<T>
將分別自動強制爲&str
,&[T]
或&T
。
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
}
現在你可以調用這些方法與更廣泛的類型。例如,可以用字符串文字("Anna"
)或分配String
來調用awesome_greeting
。可以調用total_price
參考數組(&[1, 2, 3]
)或分配Vec
。
如果你想添加或移除String
或Vec<T>
項目,可以採取可變參考(&mut String
或&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);
}
具體對於切片,您還可以接受&mut [T]
。這允許您在切片內改變特定值,但不能更改切片內的項目數量:
fn reset_first_price(prices: &mut [i32]) {
prices[0] = 0;
}
在開始時如何開始** tl; dr **?這個答案已經有些長了。像''&str'這樣的東西更普遍(如:限制較少)而沒有降低功能「?另外:第3點通常不是我認爲的那麼重要。通常'Vec's和'String's會在堆棧中生存,並且通常甚至會在當前堆棧框架附近。堆棧通常很熱並且取消引用將從CPU緩存中提供。 –
@Shepmaster:關於分配成本,當談論強制分配時,可能值得提到子串/片的特定問題。 'total_price(&prices [0..4])'不需要爲該片分配一個新的向量。 –