Is it possible to declare a related type that will represent the trait?

Is it possible to declare an associated type that will represent the trait? If not, what can I do instead? Trying to do:

trait Foo {
    /// A trait representing all types that can be returned from baz()
    type ReturnType;
    fn baz(&self) -> Self::ReturnType;
}

      

The biggest problem I have encountered is with trait Sized

, because I need a function that returns a vector of elements of a type that implements ReturnType

:

trait Foo {
    type ReturnType;
    // option 1
    fn bar(&self) -> Vec<Self::ReturnType>;
    // option 2
    fn bar<T: Self::ReturnType>(&self) -> Vec<T>;
}

      

The problem with parameter 1 is that ReturnType

it will not be sized because it is a trait, and the problem with parameter 2 is that the compiler does not recognize the associated type as a trait: failed to resolve. Use of undeclared type or module 'Self'

and use of undeclared trait name 'Self::ReturnType'

(which makes me think that associated types cannot define traits)

EDIT: An example of what I am trying to do

/// Represents all types that store byte-data instead of the actual
/// element
trait BufferedVec {
    /// the trait representing types that can be converted from the byte-data
    type FromBuffer;
    /// return the data at the given index, converted into a given type
    fn get<T: Self::FromBuffer>(&self, index: usize) -> T;
}

      

Custom implementation could be

/// An implementation of a BufferedVec
struct MyBufferedVec<'a> {
    data: &'a [Option<Vec<u8>>]
}
impl<'a> BufferedVec for MyBufferedVec<'a> {
    type FromBuffer = MyFromTrait;
    fn get<T: MyFromTrait>(&self, index: usize) -> T {
        <T as MyFromTrait>::convert(self.data[index].as_ref())
    }
}

trait MyFromTrait {
    fn convert(val: Option<&[u8]>) -> Self;
}
impl MyFromTrait for i32 {
    fn convert(val: Option<&[u8]>) -> i32 {
        match val {
             Some(ref bytes) => bytes[0] as i32,
             None            => 0
        }
    }
}
impl MyFromTrait for String {
    fn convert(val: Option<&[u8]>) -> String {
        match val {
             Some(ref bytes) => String::from_utf8(bytes),
             None            => "".to_string()
        }
    }
}

      

+3


source to share


1 answer


Bound types cannot define traits. You cannot specify traits anywhere in Rust. You can require that a generic argument (or associated type) needs a trait implementation.

trait Foo {
    type ReturnType: Clone;
}

      



Thus, any constructors Foo

need to make sure their choice ReturnType

also implements Clone

.

impl Foo for Bar {
    type ReturnType: i32;
}

      

+2


source







All Articles