TL; DR: Man kann stattdessen verwenden &str
, &[T]
oder &T
für generischen Code zu ermöglichen.
Einer der Hauptgründe für die Verwendung von a String
oder a Vec
ist, dass sie das Erhöhen oder Verringern der Kapazität ermöglichen. Wenn Sie jedoch eine unveränderliche Referenz akzeptieren, können Sie keine dieser interessanten Methoden für das Vec
oder verwenden String
.
Akzeptieren einer &String
, &Vec
oder &Box
auch erfordert das Argument auf dem Heap zugewiesen werden , bevor Sie die Funktion aufrufen kann. Das Akzeptieren von a &str
ermöglicht ein Zeichenfolgenliteral (in den Programmdaten gespeichert) und das Akzeptieren von a &[T]
oder &T
ermöglicht ein vom Stapel zugewiesenes Array oder eine Variable. Eine unnötige Zuordnung ist ein Leistungsverlust. Dies wird normalerweise sofort angezeigt, wenn Sie versuchen, diese Methoden in einem Test oder einer main
Methode aufzurufen :
awesome_greeting(&String::from("Anna"));
total_price(&vec![42, 13, 1337])
is_even(&Box::new(42))
Eine weitere Leistung Überlegung ist , dass &String
, &Vec
und &Box
eine unnötige Schicht Indirektionsebene vorstellen , wie Sie das dereferenzieren haben &String
eine zu bekommen String
und dann eine zweite dereferenzieren ausführen , um am Ende an &str
.
Stattdessen sollten Sie ein String-Slice ( &str
), ein Slice ( &[T]
) oder nur eine Referenz ( &T
) akzeptieren . A &String
, &Vec<T>
oder &Box<T>
wird automatisch in einen dazu gezwungen werden &str
, &[T]
oder &T
, respectively.
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
}
Jetzt können Sie diese Methoden mit einem breiteren Satz von Typen aufrufen. Zum Beispiel awesome_greeting
kann mit einem String - Literal (genannt werden "Anna"
) oder einem zugeordneten String
. total_price
kann mit einem Verweis auf ein Array ( &[1, 2, 3]
) oder ein zugewiesenes aufgerufen werden Vec
.
Wenn Sie Elemente zum String
oder hinzufügen oder entfernen möchten Vec<T>
, können Sie eine veränderbare Referenz ( &mut String
oder &mut Vec<T>
) verwenden:
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);
}
Speziell für Slices können Sie auch ein &mut [T]
oder akzeptieren &mut str
. Auf diese Weise können Sie einen bestimmten Wert innerhalb des Slice mutieren, aber Sie können die Anzahl der Elemente innerhalb des Slice nicht ändern (was bedeutet, dass dies für Zeichenfolgen sehr eingeschränkt ist):
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
ist allgemeiner (wie in: weniger Einschränkungen auferlegt) ohne eingeschränkte Fähigkeiten"? Außerdem: Punkt 3 ist meiner Meinung nach oft nicht so wichtig. Normalerweise lebenVec
s undString
s auf dem Stapel und oft sogar irgendwo in der Nähe des aktuellen Stapelrahmens. Der Stack ist normalerweise heiß und die Dereferenzierung wird aus einem CPU-Cache bereitgestellt.total_price(&prices[0..4])
erfordert keine Zuweisung eines neuen Vektors für das Slice.&str
und warum verwenden sollte (ich komme aus Python, daher beschäftige ich mich normalerweise nicht explizit mit Typen). Alles perfektNeben Shepmaster Antwort , zu einem anderen Grund zu akzeptieren ein
&str
(und ähnlich&[T]
usw.) wegen all der anderen Arten ist nebenString
und&str
dass auch erfüllenDeref<Target = str>
. Eines der bemerkenswertesten Beispiele istCow<str>
, dass Sie sehr flexibel entscheiden können, ob Sie mit eigenen oder geliehenen Daten arbeiten.Wenn Sie haben:
Aber Sie müssen es mit a nennen
Cow<str>
, Sie müssen dies tun:Wenn Sie den Argumenttyp in ändern
&str
, können Sie ihnCow
nahtlos und ohne unnötige Zuordnung verwenden, genau wie beiString
:Durch das Akzeptieren wird
&str
das Aufrufen Ihrer Funktion einheitlicher und bequemer, und der "einfachste" Weg ist jetzt auch der effizienteste. Diese Beispiele funktionieren auch mitCow<[T]>
usw.quelle