6

Am I missing something, or are mutable non-reference arguments not supported in Rust?

To give an example, I was playing with Rust and tried to implement Euclid's algorithm generic for all numeric types, and ideally I just wanted to pass arguments by value and have them mutable, but adding keyword mut to the argument type is rejected by compiler. So I have to declare a mutable copy of the argument as the function prologue. Is this idiomatic/efficent?

use std::ops::Rem;

extern crate num;
use self::num::Zero;

pub fn gcd<T: Copy + Zero + PartialOrd + Rem<Output=T>>(a : T, b : T) -> T
{
   let mut aa = a;
   let mut bb = b;

   while bb > T::zero() {
      let t = bb;
      bb = aa % bb; 
      aa = t;
   }

   aa
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Massimiliano
  • 16,770
  • 10
  • 69
  • 112

1 Answers1

12

It's certainly possible to say that an argument will be mutable:

use num::Zero; // 0.4.0
use std::ops::Rem;

pub fn gcd<T>(mut a: T, mut b: T) -> T
where
    T: Copy + Zero + PartialOrd + Rem<Output = T>,
{
    while b > T::zero() {
        let t = b;
        b = a % b;
        a = t;
    }

    a
}

Is [declaring a mutable copy of the argument] idiomatic/efficient?

It should be fine from an efficiency perspective. The optimizer will see that they are the same and not do any extraneous copying.

As for idiomatic, I'm not so sure. I originally started by not putting mut in my function argument list as I felt that it was oversharing details about the implementation. Nowadays, I go ahead and put it in there.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Duh! I was writing `mut` before `T`, thought it is similar to how a mutable ref type signature looks... Thanks! – Massimiliano Jul 13 '15 at 16:37
  • @MaxGalkin yup, it mirrors how a mutable variable binding is declared in other places — `let mut foo: u8 = 42`. – Shepmaster Jul 13 '15 at 16:39
  • I was looking at examples with `a : &mut T`, where `mut` is next to the type and I thought it just stays next to the type :) – Massimiliano Jul 13 '15 at 16:44
  • 5
    `mut a: T` is rendered as just `a: T` in rustdoc, so it's handled as the internal detail it is. It indeed has no effect on the function signature. – bluss Jul 13 '15 at 17:02