Предпочитают ли авторы библиотек использовать перечисления или признаки?
Предпочитают ли строители использовать гвозди или шурупы?
Поддерживают ли врачииспользовать клей, швы или скобки?
Это бессмысленная дихотомия.Обе возможности существуют, и оба используются.Люди используют правильный инструмент для конкретной работы под рукой.
Начните с того, что вернитесь назад и перечитайте Язык программирования Rust глава Is Rust a ObjectОриентированный язык программирования? .
Короче говоря, черты допускают неограниченный полиморфизм, а перечисления строго ограничены.Это главное отличие.Посмотрите, что нужно для вашей проблемной области, и используйте правильные вещи.
реализация раскрыта: подпись f
отличается в обоих примерах
Да, проектирование программного обеспеченияиногда требуется некоторое количество предварительных мыслей, заботы и дизайна.
Если вы предоставляете перечисление своим пользователям, а затем добавляете, удаляете или изменяете вариант, каждое использование этого перечисления должно быть обновлено.
Если вы предоставляете признак своим пользователям, а затем добавляете, удаляете или модифицируете метод, каждое использование этой черты должно быть обновлено.
Нет ничего особенного в том, что вы выбираетемежду перечислением или чертой, которая вызывает эту проблему.Вы также можете переименовать метод, добавить, удалить или изменить порядок параметров.Существует множество способов доставить неприятности вашим пользователям.
Если вы измените свой API, ваши пользователи будут затронуты .
Мне нужно написать универсальную функцию
Вам не нужно , нужно , но вам, вероятно, следует использовать ее по умолчанию из соображений производительности.Вы можете использовать объект-черту, например fn f(t: &T)
или fn f(t: Box<T>)
, если <T>
вызывает испуг.
написать библиотеку с перечислениями, но в конечном итоге решить, что я действительно хотел, это черты
Теперь, когда вы знаете, что не всегда нужно выбирать одно или другое,также осознайте, что вы можете использовать их вместе:
enum Pet {
Cat,
Dog,
Other(Box<Animal>),
}
trait Animal {}
trait TimeSource {
fn now() -> u64;
}
enum Builtin {
Ntp,
Sundial,
}
impl TimeSource for Builtin {
// ...
}
В личном плане, если я все еще создаю прототип своего кода и неясно, какой выбор лучше, я, вероятно, по умолчаниюиспользовать черту.Неограниченный полиморфизм лучше соответствует моим предпочтениям внедрения зависимостей и стиля тестирования.