这是程序君的 Rust 培训(1)中关于泛型的练习,教程中作者使用了Vec作为encode后的返回对象,练习时自己做了修改,支持泛型。在更进一步拓宽适用范围时,遇到了问题。依然是不长的代码,问题在注释中。大概描述一下:泛型参数T,我知道它是某种特征数据的集合,我怎么把它合并在一起?这个时候T还没确定具体类型。
use std::io::Error;
pub trait Encoder {
    type Target;
    fn encode(&self) -> Result<Self::Target, Error>;
}
#[derive(Debug)]
pub struct User<Id, Data>
{
    id: Id,
    data: Data,
}
impl<Id, Data> User<Id, Data>
{
    pub fn new(id: Id, data: Data) -> Self {
        Self { id, data }
    }
}
impl<Id, Data, T> Encoder for User<Id, Data>
where
    Id: Encoder<Target = T>,
    Data: Encoder<Target = T>,
{
    type Target = T;
    fn encode(&self) -> Result<Self::Target, Error> {
        let mut ret = self.id.encode()?;
        let mut retdata = self.data.encode()?;
        // 问题在这里,该用什么方式来表达一个类似"+"的概念,
        // 可以实现类似数组或vec的合并这样的概念,达到ret+retdat的
        // 效果,以适应更广泛的类型,比如HashMap、Array等等。
        // ret.append(&mut retdata);
        // 如果把本例中的Self::Target换成Vec<Self::Target>
        // 然后把test中的type Target = u8,那么用append就可以
        
        Ok(ret)
    }
}
#[cfg(test)]
mod tests {
    use super::*;
    impl Encoder for u64 {
        type Target = Vec<u8>;
        fn encode(&self) -> Result<Self::Target, Error> {
            let ret = self.to_le_bytes().to_vec();
            Ok(ret)        
        }
    }
    
    impl Encoder for String {
        type Target = Vec<u8>;
        fn encode(&self) -> Result<Self::Target, Error> {
            let ret = self.as_bytes().to_vec();
            Ok(ret)
        }
    }
    #[test]
    fn test_name() {
        let t1 = User::new(1, "abcdef".to_string());
        println!("t1: {:?}", t1.encode().unwrap());
        let t2 = User::new("be".to_string(), 256);
        println!("t2: {:?}", t2.encode());
    }
}
	    
	    
		1
	    
	    
	    共 5 条评论, 1 页
	
	
    
评论区
写评论研究了半天,没明白怎么用这个,还请详细指点一下,谢谢!
--
👇
7sDream: 事实上,标准库里就有你需要的 Trait:
std::iter::Extend。事实上,标准库里就有你需要的 Trait:
std::iter::Extend。这个不算自动推导吧。你再实现一个
impl Append for Vec<usize>也行啊。静态分发是你实现几个,到时候T就展开成几个。--
👇
ziyouwa: 确实可以,非常感谢!居然可以自动推导T是Vec<u8>,NB!
--
👇
uno: 最简单的,就是再定义一个trait呗
确实可以,非常感谢!居然可以自动推导T是Vec<u8>,NB!
--
👇
uno: 最简单的,就是再定义一个trait呗
最简单的,就是再定义一个trait呗