Rust equivalent to Swift's extension methods to a protocol?

人走茶凉 提交于 2021-02-05 06:30:45

问题


In Swift I can attach extension methods to any of struct, enum or protocol(same with trait in Rust).

protocol Foo1 {
    func method1() -> Int 
}
extension Foo1 {
    func method2() {
        print("\(method1())")
    }
}

Then all types conforming the protocol Foo1 now all have method2(). This is very useful to build "method chaining" easily.

How to do same in Rust? This doesn't work with an error.

struct Kaz {}

impl Foo for Kaz {}

trait Foo {
    fn sample1(&self) -> isize { 111 } 
}

impl Foo {
    fn sample2(&self) {
        println!("{}", self.sample1());
    }
}

fn main() {
    let x = Kaz {};
    x.sample1();
    x.sample2();
}

Here's the error.

warning: trait objects without an explicit `dyn` are deprecated
  --> src/main.rs:13:6
   |
13 | impl Foo {
   |      ^^^ help: use `dyn`: `dyn Foo`
   |
   = note: `#[warn(bare_trait_objects)]` on by default

error[E0599]: no method named `sample2` found for type `Kaz` in the current scope
  --> src/main.rs:22:7
   |
3  | struct Kaz {}
   | ---------- method `sample2` not found for this
...
22 |     x.sample2();
   |       ^^^^^^^ method not found in `Kaz`

error: aborting due to previous error

回答1:


In Rust, you can use extension traits, that is a trait with a generic implementation for all types T that implement the base trait:

struct Kaz {}

impl Foo for Kaz {}

trait Foo {
    fn sample1(&self) -> isize { 111 } 
}

trait FooExt {
    fn sample2(&self);
}

impl<T: Foo> FooExt for T {
    fn sample2(&self)
        println!("{}", self.sample1());
    }
}

fn main() {
    let x = Kaz {};
    x.sample1();
    x.sample2();
}

Playground



来源:https://stackoverflow.com/questions/58852640/rust-equivalent-to-swifts-extension-methods-to-a-protocol

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!