Когда использовать AsRef или другие свойства преобразования для типа типа string
Я определяю API-интерфейс ящика в Rust stable (на данный момент, версия 1.2) и недоумеваю о лучших методах определения моих собственных типов, подобных строкам.
Например, у меня есть тип Foo
, который обертывает строку.
pub struct Foo(String);
Мой API скрывает конструкцию экземпляров Foo
, и, кроме того, поскольку поле кортежа является закрытым, приложение не может ошибочно построить недопустимое значение Foo
для себя. Это означает, что мой API ограничивает применение только действительными значениями Foo
. Пока все хорошо.
Тем не менее, я хочу, чтобы приложение могло использовать экземпляр Foo
, как будто это строка, скажем, печатая ее, записывая ее, записывая в файл, передавая ее в сторонний ящик, который принимает &str
, создавая копию с помощью to_string()
и мутируя копию и т.д. Короче говоря, я хочу, чтобы приложение могло "отбросить" Foo
-ness и работать со ссылкой на базовую строку. Поскольку приложение не может преобразовать исходную строку обратно в экземпляр Foo
, сохраняется безопасность типов.
Мой вопрос: какие признаки преобразования, если таковые имеются, должны реализовать мой ящик для Foo
, чтобы приложение "отбрасывало" Foo
-ness и работало с базовой строкой в виде необработанной строки? Важно, чтобы Foo
преобразовывался в &str
, чтобы исключить любое ненужное копирование базовой строки.
Например, как насчет?
impl AsRef<str> for Foo
Правильно ли это делать? Достаточно ли идиоматично? Есть ли какие-либо другие черты преобразования, которые я должен рассмотреть для реализации для Foo
?
Ответы
Ответ 1
Если a Foo
является семантически строкой, то выполнение Deref<Target = str>
(или, возможно, Deref<Target = String>
и DerefMut
) - это главное. Это позволит &Foo
принуждать к &str
, поэтому вы можете писать такие вещи, как &*foo
, чтобы получить &str
из Foo
и foo.starts_with("bar")
и такие методы вызова, которые определены на str
.
Реализация AsRef
также будет полезной для некоторых вещей. Borrow
- это еще одна вещь, которую вы можете захотеть, хотя перед тем, как это сделать, есть вещи.