#generics #rust #enums #lifetime-scoping
#дженерики #Ржавчина #перечисления #определение области действия в течение всего срока службы
Вопрос:
Я пытаюсь создать a Result
с параметром времени жизни в качестве дополнительного ограничения для T
общих параметров ( ::Ok(T)
) и E
( ::Err(E)
).
// enums A<'a> and B<'a> elided
pub enum Result<'a, T=A<'a>, E=B<'a>> {
Ok(T),
Err(E),
}
unused parameter, suggestion: add PhantomData
Так что это не сработало. Я читал, что я могу обойти ошибку неиспользуемого параметра с PhantomData
помощью, но это кажется мне грязным.
Это тоже не сработало:
pub enum Result<T=A<'a>, E=B<'a>> {
Ok(T),
Err(E),
}
undefined parameter, suggestion: add parameter before T
(twice)
Это предложение ставит меня в тупик!
Как мне поместить универсальный type
параметр с параметром времени жизни в мое enum
общее значение параметра по умолчанию?
Комментарии:
1. Было бы полезно, если бы вы включили какой-нибудь пример кода, который показывает контекст того, что вы пытаетесь сделать. Потому что непонятно, почему использование стандарта
Result
невозможно, т.Е. Наличие возвращаемого типаResult<A<'a>, B<'a>>
.2. Вместо типов по умолчанию можно использовать псевдоним:
type MyResult<'a> = Result<A<'a>, B<'a>>;
Ответ №1:
Ошибка верна, этот тип не имеет смысла:
Поскольку время жизни используется только в параметрах по умолчанию, каким будет время жизни в подобных случаях:
let foo = Result::Ok(42); // What's the lifetime in this instance?
?
Время жизни не используется, отсюда и приходит сообщение об ошибке.
Вопрос не дает большого контекста, но похоже, что вы намерены использовать только A<'_>
and B<'_>
в своем типе. Если это так, то вы должны использовать
pub enum Result<'a> {
Ok(A<'a>),
Err(B<'a>),
}
который действителен. Однако это вызвало бы вопрос о том, почему вы не используете встроенный Result
тип, возможно, в сочетании с псевдонимом типа, чтобы избежать повторения : type Result<'a> = std::result::Result<A<'a>, B<'a>>;
.
Это довольно часто делается, даже стандартная библиотека делает это несколько раз:
std::io::Result
:type Result<T> = Result<T, Error>;
std::fmt::Result
:type Result = Result<(), Error>;
Комментарии:
1. Спасибо! Я боролся с чрезмерно длинными
Result
типами, и это не «щелкнуло», что я мог создавать псевдонимы локального типа модуля. Я все еще задаюсь вопросом, как я мог бы создатьenum
, где время жизниT
иE
всегда одинаковы, чтобы я мог создатьenum
подобноеlet e = Result<'a, A, B>
и иметь вариантыenum
стать::T<A<'a>>
и::E<B<'a>>
, но с тех пор я понял, что у меня нет практической необходимости в этом.