在 trait 中定义一个返回 Self 的默认实现的方法
Define a method in trait returning a default implementation of Self
我想要以下功能
trait Policy {
fn eval(&self, k: u32) -> bool;
fn default() -> Box<dyn Policy>
where
Self: Sized,
{
Box::new(MaxPolicy { max: 2 })
}
}
struct MaxPolicy {
max: u32,
}
impl Policy for MaxPolicy {
fn eval(&self, k: u32) -> bool {
println!("MaxPolicy");
k < self.max
}
}
#[test]
fn max_policy() {
let p = MaxPolicy { max: 2 };
assert!(!p.eval(3));
}
#[test]
fn default_policy() {
let p = Policy::default();
assert!(!p.eval(3));
}
这不编译:
error[E0283]: type annotations needed
--> src/lib.rs:31:13
|
4 | fn default() -> Box<dyn Policy>
| -------
5 | where
6 | Self: Sized,
| ----- required by this bound in `Policy::default`
...
31 | let p = Policy::default();
| ^^^^^^^^^^^^^^^ cannot infer type
|
= note: cannot resolve `_: Policy`
是否可以改变方法使其发挥作用?特征对象甚至有可能有一个方法返回 Self
的某些实现吗?如果不是,为什么不呢?
我构建了一个具有相似优点的解决方法 API
trait Policy {
fn eval(&self, k: u32) -> bool;
}
struct MaxPolicy {
max: u32,
}
impl Policy for MaxPolicy {
fn eval(&self, k: u32) -> bool {
println!("MaxPolicy");
k < self.max
}
}
struct MinPolicy {
min: u32,
}
impl Policy for MinPolicy {
fn eval(&self, k: u32) -> bool {
println!("MinPolicy");
k > self.min
}
}
enum PolicyEnum {
Custom(Box<dyn Policy>),
Default,
}
impl PolicyEnum {
const DEFAULT: MaxPolicy = MaxPolicy { max: 4 };
}
impl Policy for PolicyEnum {
fn eval(&self, k: u32) -> bool {
match self {
PolicyEnum::Custom(p) => p.eval(k),
PolicyEnum::Default => Self::DEFAULT.eval(k),
}
}
}
这样,就可以做到:
#[test]
fn default() {
let p = PolicyEnum::Default;
assert!(p.eval(3));
}
#[test]
fn custom() {
let p = PolicyEnum::Custom(Box::new(MinPolicy{min: 4}));
assert!(p.eval(5));
}
在 trait 对象类型上实现 default
,而不是在 trait 上实现:
trait Policy {
fn eval(&self, k: u32) -> bool;
}
impl dyn Policy {
fn default() -> Box<Self> {
Box::new(MaxPolicy { max: 2 })
}
}
另请参阅:
我想要以下功能
trait Policy {
fn eval(&self, k: u32) -> bool;
fn default() -> Box<dyn Policy>
where
Self: Sized,
{
Box::new(MaxPolicy { max: 2 })
}
}
struct MaxPolicy {
max: u32,
}
impl Policy for MaxPolicy {
fn eval(&self, k: u32) -> bool {
println!("MaxPolicy");
k < self.max
}
}
#[test]
fn max_policy() {
let p = MaxPolicy { max: 2 };
assert!(!p.eval(3));
}
#[test]
fn default_policy() {
let p = Policy::default();
assert!(!p.eval(3));
}
这不编译:
error[E0283]: type annotations needed
--> src/lib.rs:31:13
|
4 | fn default() -> Box<dyn Policy>
| -------
5 | where
6 | Self: Sized,
| ----- required by this bound in `Policy::default`
...
31 | let p = Policy::default();
| ^^^^^^^^^^^^^^^ cannot infer type
|
= note: cannot resolve `_: Policy`
是否可以改变方法使其发挥作用?特征对象甚至有可能有一个方法返回 Self
的某些实现吗?如果不是,为什么不呢?
我构建了一个具有相似优点的解决方法 API
trait Policy {
fn eval(&self, k: u32) -> bool;
}
struct MaxPolicy {
max: u32,
}
impl Policy for MaxPolicy {
fn eval(&self, k: u32) -> bool {
println!("MaxPolicy");
k < self.max
}
}
struct MinPolicy {
min: u32,
}
impl Policy for MinPolicy {
fn eval(&self, k: u32) -> bool {
println!("MinPolicy");
k > self.min
}
}
enum PolicyEnum {
Custom(Box<dyn Policy>),
Default,
}
impl PolicyEnum {
const DEFAULT: MaxPolicy = MaxPolicy { max: 4 };
}
impl Policy for PolicyEnum {
fn eval(&self, k: u32) -> bool {
match self {
PolicyEnum::Custom(p) => p.eval(k),
PolicyEnum::Default => Self::DEFAULT.eval(k),
}
}
}
这样,就可以做到:
#[test]
fn default() {
let p = PolicyEnum::Default;
assert!(p.eval(3));
}
#[test]
fn custom() {
let p = PolicyEnum::Custom(Box::new(MinPolicy{min: 4}));
assert!(p.eval(5));
}
在 trait 对象类型上实现 default
,而不是在 trait 上实现:
trait Policy {
fn eval(&self, k: u32) -> bool;
}
impl dyn Policy {
fn default() -> Box<Self> {
Box::new(MaxPolicy { max: 2 })
}
}
另请参阅: