这是程序君的 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呗