【问题标题】:Is it possible to declare an associated type that will represent a trait?是否可以声明一个代表特征的关联类型?
【发布时间】:2015-07-29 06:27:29
【问题描述】:

是否可以声明一个代表特征的关联类型?如果没有,我能做些什么呢?尝试做:

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

我遇到的最大问题是Sized 特征,因为我想要一个函数,它返回一个实现ReturnType 类型的项向量:

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

选项 1 的问题是 ReturnType 不会被调整大小,因为它是一个特征,选项 2 的问题是编译器不会将关联的类型识别为特征:failed to resolve. Use of undeclared type or module 'Self'use of undeclared trait name 'Self::ReturnType' (这让我认为关联类型不能指定特征)

编辑:我正在尝试做的一个例子

/// 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;
}

用户的实现可能是

/// 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()
        }
    }
}

【问题讨论】:

    标签: rust traits associated-types


    【解决方案1】:

    关联类型不能指定特征。你不能在 Rust 的任何地方指定特征。您可以要求泛型参数(或关联类型)需要实现特征。

    trait Foo {
        type ReturnType: Clone;
    }
    

    这样Foo 的任何实现者都需要确保他们选择的ReturnType 也实现了Clone

    impl Foo for Bar {
        type ReturnType: i32;
    }
    

    【讨论】:

    • 对;我想了很多
    • 您的用例是什么? Rust 很有可能为您的实际问题提供解决方案。显示使用您的特征和成员函数的代码的 MCVE 会有很大帮助。
    • 我正在尝试构建一个 API。基本上,我正在制作用户应该实现的特征以符合我的 API。问题是我希望其中一个函数返回实现用户定义的特征的东西
    • 但是由于您无论如何都不能使用该特征,因为您对此一无所知,您也可以允许用户传递任何类型。
    • 啊...泛型而不是关联类型。说得通。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 2021-10-28
    • 1970-01-01
    相关资源
    最近更新 更多