Я пытаюсь изучить Ржавчину, и, как и многие другие, я отправился писать итератор последовательности Фибоначчи для практики. Мой первый проход использовал u32
и работал отлично, поэтому я решил попробовать создать общую версию. Это мой результат:Как избежать чрезмерного клонирования в ржавчине?
use num::Integer;
use std::ops::Add;
pub struct Fibonacci<T: Integer + Add + Clone> {
nth: T,
n_plus_one_th: T,
}
impl<T: Integer + Add + Clone> Iterator for Fibonacci<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
let temp = self.nth.clone();
self.nth = self.n_plus_one_th.clone();
self.n_plus_one_th = temp.clone() + self.n_plus_one_th.clone();
Some(temp)
}
}
impl<T: Integer + Add + Clone> Fibonacci<T> {
pub fn new() -> Fibonacci<T> {
Fibonacci {
nth: T::one(),
n_plus_one_th: T::one(),
}
}
}
Я испытал это с u32
и num::BigUint
, и она отлично работает. Тем не менее, меня беспокоит все клонирование в методе next
. В частности, я не понимаю, зачем мне клонировать во время шага добавления.
Я подозреваю, что есть лучший способ написать это, используя некоторые из более продвинутых ссылочных понятий Руста, но пока я не понял этого.
Одно быстрое наблюдение: я заметил, что вы не поместили никаких ограничений на структуру непосредственно, только на реализации. Это конвенция о ржавчине? –
@MarkTozzi В основном это зависит от личных предпочтений. Вы можете повторять границы повсюду, если вы хотите сделать это более трудным для «неправильного использования» типа, но для примера это казалось излишним. –
В том случае, если кто-то тоже задается вопросом: конструкция «где для» называется («Магия») «Ранжирование признаков более высокого ранга» (HRTB) и документируется здесь https://doc.rust-lang.org/nomicon/hrtb. HTML – Sebastian