Какой идиоматический способ передать изменяемое значение?

Я что-то упустил или изменяемые нереферентные аргументы не поддерживаются в Rust?

Чтобы привести пример, я играл с Rust и пытался реализовать алгоритм Евклида, универсальный для всех числовых типов, и в идеале я просто хотел передать аргументы по значению и сделать их изменяемыми, но добавив ключевое слово mut тип аргумента отклоняется компилятором. Поэтому я должен объявить изменяемую копию аргумента как пролог функции. Это идиоматично / эффективно?

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
}

1 ответ

Решение

Конечно, можно сказать, что аргумент будет изменчивым:

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
}

Является ли [объявление изменчивой копии аргумента] идиоматическим / эффективным?

Это должно быть хорошо с точки зрения эффективности. Оптимизатор увидит, что они одинаковы, и не будет делать никакого постороннего копирования.

Что касается идиоматических, я не так уверен. Я изначально начал с того, что не ставил mut в моем списке аргументов функции, так как я чувствовал, что это было подробное описание реализации. В настоящее время я продолжаю и помещаю это там.

Другие вопросы по тегам