最近升级之前写的一个oauth2 相关[1]的依赖时(深度解读-如何用keycloak管理external auth), 发现新版oauth2-rs[2]有些实现 pattern 很有意思,可以展开看看。
今天先看下sealed trait
。
这种 pattern 是用来当自己的 trait 想限定一些实现方法时使用。
常规的 trait 定义都是很灵活的,不限定实现
比如下边nosealed_trait
可以分别为usize
和i32
实现。
mod nosealed_trait {
pub trait MyTrait {
fn my_sealed_method(&self);
}
}
impl nosealed_trait::MyTrait for usize {
fn my_sealed_method(&self) {
println!("MyTrait for usize");
}
}
impl nosealed_trait::MyTrait for i32 {
fn my_sealed_method(&self) {
println!("MyTrait for i32");
}
}
那如果只想为i32
实现呢?
可以让自己trait
依赖一个不暴露的super trait
,由super trait
限定能有哪些实现
mod sealed_trait {
mod private {
pub trait Sealed {}
impl Sealed for i32 {}
}
pub trait MySealedTrait: private::Sealed {
fn my_sealed_method(&self);
}
}
impl sealed_trait::MySealedTrait for i32 {
fn my_sealed_method(&self) {
println!("MySealedTrait for i32");
}
}
如果调用方想实现不在限定实现列表中的方法就会被编译错误阻止。
代码语言:javascript复制impl sealed_trait::MySealedTrait for usize {
fn my_sealed_method(&self) {
println!("MySealedTrait for usize");
}
}
错误如下, 其中的note
说的很明白。
代码语言:javascript复制note:
MySealedTrait
is a "sealed trait", because to implement it you also need to implementsealedtrait::private::Sealed
, which is not accessible; this is usually done to force you to use one of the provided types that already implement it
error[E0277]: the trait bound `usize: Sealed` is not satisfied
--> src/main.rs:34:37
|
34 | impl sealedtrait::MySealedTrait for usize {
| ^^^^^ the trait `Sealed` is not implemented for `usize`
|
= help: the trait `Sealed` is implemented for `i32`
note: required by a bound in `MySealedTrait`
--> src/main.rs:23:30
|
23 | pub trait MySealedTrait: private::Sealed {
| ^^^^^^^^^^^^^^^ required by this bound in `MySealedTrait`
= note: `MySealedTrait` is a "sealed trait", because to implement it you also need to implement `sealedtrait::private::Sealed`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it
= help: the following type implements the trait:
i32
下一篇再聊聊typestate pattern
.
参考资料
[1]
oauth2 相关: https://github.com/NewbMiao/axum-koans/
[2]
oauth2-rs: https://github.com/ramosbugs/oauth2-rs