rust - 从原始库`use super`重构impl
问题描述
我仍在学习 Rust,并尝试rust-cssparser
重新使用源库中定义的 impl,但得到编译错误,cannot define inherent impl for a type outside of the crate where the type is defined
. 当然,图书馆使用use super::Token;
,但我需要use cssparser::{ Token };
,并且不知道如何解决。https://github.com/servo/rust-cssparser/blob/master/src/serializer.rs#L503-L552
摘抄:
impl<'a> Token<'a> {
/// Categorize a token into a type that determines when `/**/` needs to be inserted
/// between two tokens when serialized next to each other without whitespace in between.
///
/// See the `TokenSerializationType::needs_separator_when_before` method.
pub fn serialization_type(&self) -> TokenSerializationType {
use self::TokenSerializationTypeVariants::*;
TokenSerializationType(match *self {
Token::Ident(_) => Ident,
Token::AtKeyword(_) | Token::Hash(_) | Token::IDHash(_) => AtKeywordOrHash,
...
})
}
}
基于帮助note: define and implement a trait or new type instead
和一些搜索,我在下面尝试了几个变体,但我没有深入了解编译错误的杂草。谢谢你的帮助。
use cssparser::{
Token as Tkn,
// Token
};
// struct Token<'a>(Tkn<'a>); // requires changing lots of refs
type Token<'a> = Tkn<'a>;
解决方案
您不能重新实现已在您的 crate 之外声明的类型。这是因为任何impl <'a> Token<'a>
其他使用Token
. 通过重新实现,相同类型的实现在 crate 之间会有所不同,这就是不允许这样做的原因。
解决方案
正确的做法是SerializationType
用serialization_type
函数声明一个特征,然后实现SerializationType
for Token
。
pub trait SerializationType<'a> {
fn serialization_type(&self) -> TokenSerializationType;
}
impl<'a> SerializationType<'a> for Token<'a> {
fn serialization_type(&self) -> TokenSerializationType {
use self::TokenSerializationTypeVariants::*;
TokenSerializationType(match *self {
Token::Ident(_) => Ident,
Token::AtKeyword(_) | Token::Hash(_) | Token::IDHash(_) => AtKeywordOrHash,
...
})
}
}
替代解决方案
另一种解决方案是创建一个新类型。请注意,别名类型不会创建新类型,因此会触发相同的错误。
pub type CustomToken<'a> = Token<'a>;
您应该封装Token<'a>
到一个结构中,然后实现该结构:
struct CustomToken<'a>(Token<'a>);
impl <'a> CustomToken<'a> {
fn serialization_type(&self) -> TokenSerializationType {
use self::TokenSerializationTypeVariants::*;
TokenSerializationType(match *self {
Token::Ident(_) => Ident,
Token::AtKeyword(_) | Token::Hash(_) | Token::IDHash(_) => AtKeywordOrHash,
...
})
}
}
在我看来,基于特征的解决方案更好。
推荐阅读
- android - 为 Presenter 的私有方法编写单元测试
- python - 从字符串中提取数值并保存到数据框中的问题
- python-3.x - 如何在 python 中使用 opencv 设置图像 dpi?
- regex - How to replace datas inside a curly braces in TCL?
- python - 为自定义类赋值
- javascript - 我想移动多个数组列表中的元素
- c++ - 如何使用 mingw 使 g++ 命令在 VSCode 中工作
- javascript - 为什么不是单个表单元素在控制器中没有返回值?
- reactjs - 在 react redux 应用程序中手动导航时状态丢失
- ios - 在 iPhone 5s 上合并音频到视频的问题