Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any downside to overloading functions in rust using a trait & generic function?

Tags:

rust

I find this is particularly useful pattern to allow method overloading:

struct Foo {
  value:uint
}

trait HasUIntValue {
  fn as_uint(self) -> uint;
}

impl Foo {
  fn add<T:HasUIntValue>(&mut self, value:T) {
    self.value += value.as_uint();
  }
}

impl HasUIntValue for int {
  fn as_uint(self) -> uint {
    return self as uint;
  }
}

impl HasUIntValue for f64 {
  fn as_uint(self) -> uint {
    return self as uint;
  }
}

#[test]
fn test_add_with_int()
{
  let mut x = Foo { value: 10 };
  x.add(10i);
  assert!(x.value == 20);
}

#[test]
fn test_add_with_float()
{
  let mut x = Foo { value: 10 };
  x.add(10.0f64);
  assert!(x.value == 20);
}

Is there any meaningful downside to doing this?

like image 695
Doug Avatar asked Jul 21 '14 04:07

Doug


2 Answers

There is at least one downside: it cannot be an afterthought.

In C++, ad-hoc overloading allows you to overload a function over which you have no control (think 3rd party), whereas in Rust this is not actually doable.

That being said, ad-hoc overloading is mostly useful in C++ because of ad-hoc templates, which is the only place where you cannot know in advance which function the call will ultimately resolve to. In Rust, since templates are bound by traits, the fact that overloading cannot be an afterthought is not an issue since only the traits functions can be called anyway.

like image 107
Matthieu M. Avatar answered Nov 15 '22 08:11

Matthieu M.


No, there is no downside; this is exactly the pattern to implement overloading in Rust.

There are a number of types in the standard library which do exactly this. For example, there is BytesContainer trait in path module, which is implemented for various kinds of strings and vectors.

like image 44
Vladimir Matveev Avatar answered Nov 15 '22 07:11

Vladimir Matveev