我正在尝试使此过滤器正常工作,我的其他测试通过了,但是find_by
函数未编译。我收到一个错误no field name on type T
。关于过滤器访问字段,我在这里缺少什么?我制作了没有泛型的此代码版本,并且可以正常工作。
这是我的代码:
pub struct Repository<T> {
store: Vec<T>
}
impl<T> Repository<T> {
pub fn create() -> Repository<T> {
Repository::<T> {
store: vec![]
}
}
pub fn find_all(self) -> Vec<T> {
self.store
}
pub fn add(&mut self, item: T) {
&mut self.store.push(item);
}
// this method returns an error
pub fn find_by(self, name: &str) -> Vec<T> {
self.store.into_iter().filter(|&e| e.name == name).collect()
}
}
#[cfg(test)]
mod tests {
use super::*;
// ...
#[test]
fn can_find_objects_in_repository_by_param() {
#[derive(Debug, PartialEq)]
pub struct Cat { pub name: String };
impl Cat {
pub fn create(name: &str) -> Cat { Cat { name: name.to_string() } }
}
let mut repo = Repository::<Cat>::create();
let c1 = Cat::create("Mittens");
let c2 = Cat::create("Tiger");
repo.add(c1);
repo.add(c2);
assert_eq!(repo.find_by("Tiger"), vec![Cat { name: "Tiger".to_string() }]);
}
}
如果删除过滤器,代码将编译,并且测试将失败,并出现以下预期的错误:
left: `[Cat { name: "Mittens" }, Cat { name: "Tiger" }]`,
right: `[Cat { name: "Tiger" }]`'
答案 0 :(得分:1)
如果您定义Named
将实现的特征Cat
,则该方法有效。此特征包含name()
方法,从而解决了您的问题。
这是要应用的主要更改:
// …
pub trait Named {
fn name(&self) -> &str;
}
impl<T> Repository<T> where T: Named {
// …
// this method returns an error
pub fn find_by(self, name: &str) -> Vec<T> {
self.store.into_iter().filter(|e| e.name() == name).collect()
}
// …
#[cfg(test)]
mod tests {
// …
impl Named for Cat {
fn name(&self) -> &str {
&self.name
}
}
在锈蚀操场上见the whole code。