Wie schreibe ich eine Funktion, die sowohl eigene als auch nicht-besitzende Zeichenkettensammlungen verwendet?

8

Ich habe Probleme beim Schreiben einer Funktion, die eine Sammlung von Strings als Parameter akzeptiert. Meine Funktion sieht so aus:

%Vor%

Alles geht gut, wenn ich ein Vec<&'a str> wie erwartet an die Funktion übergebe. Wenn ich jedoch ein Vec<String> übergebe, beschwert sich der Compiler:

%Vor%

Dies wird hauptsächlich verwendet:

%Vor%

Meine Funktion kann keine Vektoren von eigenen Strings aufnehmen. Umgekehrt, wenn ich den Typ StrList in:

ändere %Vor%

Der erste Aufruf schlägt fehl und der zweite funktioniert.

Eine mögliche Lösung besteht darin, auf diese Weise ein Vec<&'a str> von v2 zu erzeugen:

%Vor%

Aber es scheint mir sehr seltsam. my_func sollte sich nicht um den Besitz der Zeichenfolgen kümmern.

Welche Art von Signatur sollte ich für my_func verwenden, um beide Vektoren von eigenen Strings und String-Referenzen zu unterstützen?

    
mbrt 22.09.2015, 18:02
quelle

2 Antworten

15

Obwohl String und &str sehr eng verwandt sind, sind sie nicht identisch. Hier sehen Sie, wie Ihre Vektoren im Speicher aussehen:

%Vor%

Hier ist jede Zeile die gleiche Menge an Speicher (vier oder acht Bytes je nach Zeigergröße). Du kannst nicht die Erinnerung an eine von diesen nehmen und sie wie die andere behandeln. Das Speicherlayout stimmt nicht überein. Die Artikel sind unterschiedlich groß und haben ein unterschiedliches Layout. Wenn beispielsweise v1 seine Artikel ab der Adresse X speichert und v2 seine Artikel ab der Adresse Y speichert, dann ist v1[1] auf der Adresse X + 8 , aber v2[1] auf der Adresse Y + 12 .

Was Sie tun können schreiben Sie eine generische Funktion wie folgt:

%Vor%

Dann kann der Compiler entsprechenden Code sowohl für &[String] und &[&str] als auch für andere Typen generieren, wenn sie AsRef<str> implementieren.

    
delnan 22.09.2015, 18:51
quelle
3

Um auf delnans großer Antwort aufzubauen, möchte ich auf eine weitere Ebene von Generika hinweisen, die Sie hier hinzufügen können. Du hast gesagt:

  

eine Sammlung von Strings

Aber es gibt mehr Arten von Sammlungen als Schnitte und Vektoren! In Ihrem Beispiel geht es Ihnen um den einmaligen Zugriff auf die Elemente. Dies ist ein perfektes Beispiel für Iterator . Im Folgenden habe ich Ihre Funktion so geändert, dass sie jeden Typ akzeptiert, der in einen Iterator umgewandelt werden kann. Sie können dann viele weitere Arten von Dingen passieren. Ich habe ein HashSet als Beispiel verwendet, aber beachten Sie, dass Sie auch v1 und v2 anstelle von &v1 oder &v2 übergeben können, indem Sie sie verbrauchen.

%Vor%     
Shepmaster 23.09.2015 16:07
quelle

Tags und Links