下面的代码是从tantivy源码里摘出来的,对T: Tokenizer + Clone,实现TokenizerClone,而Tokenizer本身有 TokenizerClone 的约束,这不就死循环了嘛?为啥能编译通过?
pub trait Tokenizer: 'static + Send + Sync + TokenizerClone {
/// Creates a token stream for a given `str`.
fn token_stream<'a>(&self, text: &'a str) -> BoxTokenStream<'a>;
}
pub trait TokenizerClone {
fn box_clone(&self) -> Box<dyn Tokenizer>;
}
impl<T: Tokenizer + Clone> TokenizerClone for T {
fn box_clone(&self) -> Box<dyn Tokenizer> {
Box::new(self.clone())
}
}
按我的思路只能写出下面的代码,尽管能工作,但api体验没上面的好:用户定义的结构需要derive(Clone)和实现TokenizerBase,但使用时用Tokenizer;而用上面的方式实现和使用都是Tokenizer,甚至有可能可以将TokenizerClone设置为私有,减小api surface。
pub trait TokenizerBase: 'static + Send + Sync {
/// Creates a token stream for a given `str`.
fn token_stream<'a>(&self, text: &'a str) -> BoxTokenStream<'a>;
}
pub trait Tokenizer: TokenizerBase {
fn box_clone(&self) -> Box<dyn Tokenizer>;
}
impl<T:TokenizerBase + Clone> Tokenizer for T {
fn box_clone(&self) -> Box<dyn Tokenizer> {
Box::new(self.clone())
}
}
1
共 2 条评论, 1 页
评论区
写评论能通过编译是因为这两个都只是约束吧,只要同时提供两者的实现就能满足了。虽然我也觉得有点迷惑。
--
👇
whfuyn: 这能不能看作是在表达trait A和trait B必须同时实现?
这能不能看作是在表达trait A和trait B必须同时实现?