Уточнение типа одного из методов трейта


#1

День добрый, господа.

Коим образом для одной из функций трейта уточнить тип ?

pub trait GetValue {
    type Value;
    fn get_value(self) -> Option<Self::Value>;
    fn get_mutref(&self) -> Option<&mut Self::Value>;
    fn get_cloned_value(self) -> Option<Self::Value>;
}

Так ругается что conflicting implementation

impl<T> GetValue for UserType<T> {
    type Value = T;
 fn get_value(self) -> Option<T>;
 fn get_mutref(&self) -> Option<&mut T>;
}
impl<T: Clone> GetValue for UserType<T> {
    type Value = T;
fn get_cloned_value(self) -> Option<T>;
}

#2

Вероятно придётся новый трейт создавать. Неудобно, хочу всего лишь функцию вызывать как метод приходится трейты городить. Хочу как в D.


#3

я так понимаю что специализация сейчас реализована не полностью - http://aturon.github.io/2018/04/05/sound-specialization/

сейчас можно только так:

impl<T> GetValue for UserType<T> // для всех вообще
impl GetValue for UserType<ConcreteType> // для конкретного


#4

Небольшое замечание: скорее всего данный метод должен получать &self


#5

А чем такой вариант не угодил?

impl<T> UserType<T> {
    fn get_value(self) -> Option<T> { ... }
    fn get_mutref(&self) -> Option<&mut T> { ... }
}

impl<T: Clone> UserType<T> {
    fn get_cloned_value(self) -> Option<T> { ... }
}

#6

О, хотел бы так, но там выходит такой вот тип

impl<T> Option<*mut Node<T>> {
     fn get_cloned_value(&self) -> Option<T> {}
}

На что раст ругается: cannot define inherent impl for a type outside of the crate where the type is defined
Тайп алиас, естественно, всего лишь бантик, который ситуацию не спасает

type UserType<T> = Option<*mut Node<T>>

#7

Newtype pattern тут поможет

pub struct UserType<T> {
inner: Option<*mut Node<T>>
}

Хотя тут конечно очень стремно получается, надо смотреть все в целом.


#8

Option тут вообще не нужно трогать, лучше сделать так:

struct UserType<T>(*mut Node<T>);

impl<T> UserType<T> {
     fn get_cloned_value(&self) -> Option<T> {}
}

Но вообще да, хорошо бы знать задачу, потому что использование *mut уже настораживает :slight_smile:

Если же хочется прямо в Option что-то добавить, то нужно использовать свой типаж:

trait UserTrait<T> {
    fn get_cloned_value(&self) -> Option<T>;
}

impl<T> UserTrait<T> for Option<*mut Node<T>> {
     fn get_cloned_value(&self) -> Option<T> { None }
}