rust - manejo - que es una cadena en programacion
Cuándo usar AsRef u otros rasgos de conversión para tipo cadena (1)
Si un Foo
es semánticamente una cadena, entonces la implementación de Deref<Target = str>
(o posiblemente Deref<Target = String>
y DerefMut
) es lo principal que se debe hacer. Eso le permitirá a &Foo
presionar a &str
, para que pueda escribir cosas como &*foo
para obtener un &str
de un Foo
, y foo.starts_with("bar")
y otros métodos de llamada que están definidos en str
.
La implementación de AsRef
también será beneficiosa para algunas cosas. Borrow
es otra cosa que puede querer tener, aunque hay cosas que considerar antes de hacerlo .
Estoy definiendo una API de caja en Rust estable (a partir de ahora, versión 1.2) y estoy perplejo sobre las mejores prácticas para definir mis propios tipos de cadenas.
Por ejemplo, tengo un tipo Foo
que envuelve una cadena.
pub struct Foo(String);
Mi API oculta la construcción de instancias de Foo
y, además, como el campo de tuplas es privado, la aplicación no puede construir erróneamente un valor de Foo
no válido para sí mismo. Esto significa que mi API restringe la aplicación para que funcione solo con valores válidos de Foo
. Hasta aquí todo bien.
Sin embargo, quiero que la aplicación pueda usar una instancia de Foo
como si fuera una cadena, digamos, imprimiéndola, registrándola, escribiéndola en un archivo, pasándola a una caja de terceros que acepte &str
, construyendo una copia vía to_string()
y mutando la copia, etc. En resumen, quiero que la aplicación pueda "descartar" Foo
-ness y trabajar con una referencia a la cadena subyacente. Como la aplicación no puede convertir la cadena cruda a una instancia de Foo
, se conserva la seguridad de tipo.
Mi pregunta es: ¿Qué rasgos de conversión, si hay alguno, debería implementar mi caja para que Foo
permita que la aplicación "elimine" Foo
-ness y trabaje con la cadena subyacente como una cadena sin formato? Es importante que Foo
convierta a &str
para evitar cualquier copia innecesaria de la cadena subyacente.
Por ejemplo, ¿qué tal?
impl AsRef<str> for Foo
¿Es eso lo correcto? ¿Es suficiente ser idiomático? ¿Hay algún otro rasgo de conversión que debería considerar implementar para Foo
?