简体   繁体   中英

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM