Rust设计模式:sealed trait

最近升级之前写的一个oauth2相关的依赖时, 发现新版oauth2-rs有些实现pattern很有意思,可以展开看看。

今天先看下sealed trait

这种pattern是用来当自己的trait想限定一些实现方法时使用。

常规的trait定义都是很灵活的,不限定实现

比如下边nosealed_trait可以分别为usizei32实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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限定能有哪些实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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");
}
}

如果调用方想实现不在限定实现列表中的方法就会被编译错误阻止。

1
2
3
4
5
impl sealed_trait::MySealedTrait for usize {
fn my_sealed_method(&self) {
println!("MySealedTrait for usize");
}
}

错误如下, 其中的note说的很明白。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.

如有疑问,请文末留言交流或邮件:newbvirgil@gmail.com 本文链接 : https://newbmiao.github.io/2024/04/22/rust-sealed-trait.html