Ich bin in Rust stabil eine Kiste API definieren (ab sofort Version 1.2) und ist perplex über Best Practices für meine eigenen strangartige Typen definieren.Wenn AsRef oder andere Umwandlungseigenschaften für strangartigen Typen verwenden
Zum Beispiel, ich habe einen Foo
Typen, der eine Zeichenfolge umschließt.
pub struct Foo(String);
Meine API verbirgt Bau von Foo
Instanzen, und darüber hinaus, weil das Tupel Feld privat ist, kann die Anwendung nicht versehentlich einen ungültigen Foo
Wert für sich selbst konstruieren. Das bedeutet, dass meine API die Anwendung so einschränkt, dass sie nur mit gültigen Foo
Werten arbeitet. So weit, ist es gut.
Allerdings mag ich die Anwendung in der Lage sein, eine Foo
Instanz zu verwenden, als ob es ein String-Sagen, es drucken, es Protokollierung in eine Datei schreiben, um es zu einer Dritt Kiste vorbei, die &str
akzeptiert, eine Kopie über to_string()
und Mutieren der Kopie, usw. kurz gesagt konstruieren, möchte ich die Anwendung auf die zugrunde liegenden String mit einem Verweis auf der Lage sein, „wegzuwerfen“ Foo
-ness und arbeiten. Da die Anwendung die Raw-Zeichenfolge nicht zurück in eine Foo
Instanz konvertieren kann, wird type-safety beibehalten.
Meine Frage ist: Welche Konvertierungsmerkmale, wenn überhaupt, sollte meine Kiste für Foo
implementieren, damit die Anwendung Foo
-ness "wegwerfen" und mit der zugrunde liegenden Zeichenfolge als eine rohe Zeichenfolge arbeiten? Es ist wichtig, dass Foo
in &str
konvertiert wird, um unnötiges Kopieren der zugrunde liegenden Zeichenfolge zu vermeiden.
Zum Beispiel, wie etwa?
impl AsRef<str> for Foo
Ist das das Richtige? Ist es genug, um idiomatisch zu sein? Gibt es andere Conversion-Merkmale, die ich für Foo
implementieren sollte?
Ihr 'starts_with' Beispiel löscht eine Menge auf. Ich habe jedoch den Buchabschnitt über 'AsRef' und' Borrow' gelesen - immer noch nicht klar. Erlaubt 'AsRef' die Nötigung zu einem' & str', ohne jedoch das 'starts_with' Beispiel zu berücksichtigen? In welchen Fällen sollte ich 'AsRef anstelle von' Deref' implementieren? Sollte ich beides umsetzen? –
'Deref' ist magisch und kann für einen Typ gemacht werden. 'AsRef' ist komplett nicht-magisch und kann für mehrere Typen verwendet werden. Beide zu implementieren ist üblich. –