turtle
turtle

Reputation: 8073

How to write a generic function in Rust that can accept any struct that implements a specific property?

I am trying to understand generics in Rust and have attempted to write a generic function that can multiple any struct that has the property foo by 10. When I use this code, I get the error, no field foo on type T.

struct A {
    foo: i8,
    bar: String,
}

struct B {
    foo: i8,
}

fn go<T>(v: T) {
    v.foo * 10
}

fn main() {
  let a = A {foo: 1, bar: "bar".to_string()};
  let b = B {foo: 2};
  println!("{:?},{:?}", go(a), go(b))
}

How can I write a generic function that can accept any struct that implements a foo: i8 property?

Upvotes: 2

Views: 2460

Answers (1)

bk2204
bk2204

Reputation: 76409

Rust doesn't have properties in the way that JavaScript does, so you need to do things a little differently. You'll want to use a trait to expose the foo functionality as a method, and then implement that trait for A and B:

trait Foo {
    fn foo(&self) -> i8;
}

struct A {
    foo: i8,
    bar: String,
}

impl Foo for A {
    fn foo(&self) -> i8 {
        self.foo
    }
}

struct B {
    foo: i8,
}

impl Foo for B {
    fn foo(&self) -> i8 {
        self.foo
    }
}

fn go<T: Foo>(v: T) -> i8 {
    v.foo() * 10
}

fn main() {
    let a = A {
        foo: 1,
        bar: "bar".to_string(),
    };
    let b = B { foo: 2 };
    println!("{:?},{:?}", go(a), go(b))
}

(Note that I also made go return a value above.)

This provides a Foo trait that exposes foo as a method, implements it for A and B, and then makes go require T to implement Foo. That's the easiest and most straightforward way to accomplish this goal.

Upvotes: 9

Related Questions