2015-07-13 7 views
5

Fehle ich etwas oder sind veränderbare Nicht-Referenz-Argumente in Rust nicht unterstützt?Was ist der idiomatische Weg, um wandelbaren Wert zu übergeben?

ein Beispiel geben, ich mit Rust spiele und versuchte Euclid's algorithm generic für alle numerischen Typen zu implementieren, und im Idealfall Ich wollte nur Argumente von Wert zu übergeben und sie wandelbar, aber mut das Argument Typ Schlüsselwort hinzugefügt wird abgelehnt durch Compiler. Also muss ich eine veränderbare Kopie des Arguments als Funktionsprolog deklarieren. Ist das idiomatisch/effizient?

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 
} 

Antwort

9

Es ist sicherlich möglich, zu sagen, dass ein Argument wandelbar sein wird:

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 
} 

[a änderbare Kopie des Arguments erklärt] idiomatische/leistungsfähig?

Aus Effizienzsicht sollte es in Ordnung sein. Der Optimierer erkennt, dass sie identisch sind und keine externen Kopien erstellen.

Wie für idiomatische bin ich mir nicht so sicher. Ich fing ursprünglich an, indem ich mut in meine Funktionsargumentliste nicht einsetzte, da ich fühlte, dass es Details über die Implementierung überlagert hatte. Heute gehe ich vor und lege es dort hinein.

+0

Duh! Ich schrieb "mut" vor "T", dachte, es ist ähnlich wie eine veränderliche ref-Typ-Signatur aussieht ... Danke! –

+0

@MaxGalkin yup, es spiegelt wider, wie eine veränderbare variable Bindung an anderen Stellen erklärt wird - 'let mut foo: u8 = 42'. – Shepmaster

+0

Ich betrachtete Beispiele mit 'a: & mut T', wobei' mut' neben dem Typ ist und ich dachte, es bleibt nur neben dem Typ :) –

Verwandte Themen