#rust #traits
#Ржавчина #Трейты
Вопрос:
Например, я хочу написать признак для контейнеров в Rust:
trait Container: Default {
type ValueType;
}
Но также я хочу, чтобы все Container
s также могли Clone
быть разделены только тогда, когда Container::ValueType
могут быть разделены Clone
:
// not Rust code
trait Container: Default Clone if Self::ValueType: Clone {
type ValueType;
}
Конечно, я мог бы условно реализовать Clone
признак для самого конкретного контейнера:
struct MyVec<T> {}
impl<T: Clone> Clone for MyVec<T> {/**/}
или использовать derive(Clone)
, но я хочу выразить свое намерение для Container
trait , а не для реализации типов.
Ответ №1:
Существует аналогичный синтаксис:
trait Container: Default Clone where Self::ValueType: Clone {
// ^^^^^
type ValueType;
}
Но это не условно, Container
может быть реализовано только для типов, которые соответствуют всем ограничениям: Default
, Clone
, и Self::ValueType
is Clone
.
Я не уверен, что это было бы полезно. Ограничения Rust trait являются явными, что означает, что вы не можете использовать что-либо, если нет ограничения. Так что вам все равно придется включить их в ограничения.
fn use_container<C: Container>(c: C)
where
C: Clone,
C::ValueType: Clone
{
let _ = c.clone();
let _ = c.get_element().clone();
}
И вы должны реализовать Clone
на конкретных типах независимо.
Если ваша цель состоит в том, чтобы просто указать, что «для реализаций Container
, если элементы Clone
, то контейнер должен быть клонирован», преобладающий шаблон в идиоматическом Rust заключается в том, чтобы ограничивать только то, что вам нужно, когда вам это нужно. (т. Е. Если функции необходимо клонировать контейнер, ограничивать on C: Clone
; если функция тольконеобходимо клонировать элемент, ограничить C::ValueType: Clone
).
Комментарии:
1. Я никогда
where Self::ValueType: Clone
раньше не видел синтаксиса. Является ли значение таким же, как при указании ограничения наValueType
само использованиеtype ValueType: Clone
?2. @user4815162342 В этом случае они были бы одинаковыми, и я бы предпочел последнее.
where
Синтаксис доступен, поскольку он может применяться к большему количеству вещей. Например:trait Container: Iterator where Self::Item: Clone
.3. О, верно, это имеет смысл, и я видел это в этом варианте. В более сложных признаках это часто определяется как
where <Self as Iterator>::Item: Clone
.