I'm trying to implement something in Rust that works like a C++ virtual function in a class, I would have a base struct with data, then I would keep some functions undefined, like the following example:
class A {
int stuff;
public:
virtual void foo(int a, int b) = 0;
void function_that_calls_foo() { /*...*/ foo(1, 2); /*...*/ }
}
class B: public A { void foo(int a, int b) { /* ... */ } }
I was trying to implement it using function pointers, but without much success. I could use a trait with A's functions, and implement A on the other class, but I would lose the struct's data. What's the best (fastest?) way to implement this kind of thing in Rust?
struct A {
...
}
impl A {
fn function_that_calls_foo(&self) {
...
self.foo(a, b);
...
}
}
struct B {
a: A;
}
impl B {
fn xxx(&self) {
a.function_that_calls_foo(1, 2);
}
fn foo(&self, a: i32, b: i32) {...}
}
keep some functions undefined
I'm adding the implicit "and have some functions that call that to-be-defined function".
As E_net4 says, use a trait:
trait Foo {
fn foo(&self, a: i32, b: i32) -> i32;
fn function_that_calls_foo(&self) {
println!("{}", self.foo(1, 2));
}
}
You can then implement the trait for Base
:
struct Base {
stuff: i32,
}
impl Foo for Base {
fn foo(&self, a: i32, b: i32) -> i32 {
self.stuff + a + b
}
}
And as Matthieu M. says, Rust doesn't have inheritance, so use composition:
struct Base {
stuff: i32,
}
impl Base {
fn reusable(&self) -> i32 {
self.stuff + 1
}
}
struct Alpha {
base: Base,
modifier: i32,
}
impl Foo for Alpha {
fn foo(&self, a: i32, b: i32) -> i32 {
(self.base.reusable() + a + b) * self.modifier
}
}
You can combine the two concepts as well, by taking a generic that is constrained by a type parameter.
I'll strongly second Dietrich Epp's point. Using a new language should involve checking out new paradigms. Inheritance for the purposes of code reuse is not usually a great idea, even in languages that support it. Instead, create smaller building blocks and combine them together.