【问题标题】:Provide default trait implementation based on trait type parameter提供基于 trait 类型参数的默认 trait 实现
【发布时间】:2017-10-06 00:04:18
【问题描述】:

鉴于这个特点:

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&lt;Vec&lt;u8&gt;&gt; 时可用,这是有道理的。但是,我希望每个实现Asset&lt;D&gt; 的类型都有load_data,如果D 实现From&lt;Vec&lt;u8&gt;&gt;,那么它使用默认实现。否则,该类型必须自己实现 load_data

【问题讨论】:

    标签: generics rust traits


    【解决方案1】:

    您可以为实现From&lt;Vec&lt;u8&gt;&gt; 的任何类型的特征一揽子实现

    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? 的逻辑相反)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-03
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 2021-09-13
      • 2015-05-31
      • 1970-01-01
      相关资源
      最近更新 更多