提供基于特征类型参数的默认特征实现

时间:2017-10-06 00:04:18

标签: generics rust traits

考虑到这个特点:

use std::io::{self, Read};
use std::fs::File;

pub trait Asset<D> {
    fn load_data(path: &str) -> io::Result<D>
    where
        D: From<Vec<u8>>
    {
        let file = File::open(path)?;
        let bytes_result: io::Result<Vec<u8>> = file.bytes().collect();

        Ok(D::from(bytes_result?))
    }

    // many more methods...
}

load_data方法仅在D实施From<Vec<u8>>时可用,这是有道理的。但是,我希望实现Asset<D>的每个类型都有load_data,如果D实现From<Vec<u8>>,则它使用默认实现。否则,类型必须自己实现load_data

1 个答案:

答案 0 :(得分:1)

您可以为实现From<Vec<u8>>的任何类型提供特征的一揽子实施

use std::io::{self, Read};
use std::fs::File;

pub trait Asset<D> {
    fn load_data(path: &str) -> io::Result<D>;

    // many more methods...
}

impl<D> Asset<D> for D
where
    D: From<Vec<u8>>,
{
    fn load_data(path: &str) -> io::Result<D> {
        let file = File::open(path)?;
        let bytes_result: io::Result<Vec<u8>> = file.bytes().collect();

        Ok(D::from(bytes_result?))
    }
}

struct Other;

impl Asset<Other> for Other {
    fn load_data(_path: &str) -> io::Result<Other> {
        unimplemented!()
    }
}

impl Asset<f64> for Other {
    fn load_data(_path: &str) -> io::Result<f64> {
        unimplemented!()
    }
}

您可能希望使用Into代替From(它与When should I implement std::convert::From vs std::convert::Into?的逻辑相反)