2015-08-19 14 views
5

Yeni bir vektör oluşturmak ve argüman vektörlerinin artık alakalı olmadığına ve yok edilmek zorunda olduklarına, bunların sahipliğini almasına yardımcı olmak için güzel bir işlev istiyorum. Özellikle bağımsız değişkenlerden herhangi birini yapmak zorunda olmamak (append, extend veya push_all kullanmak ve bu nedenle çağrı imzasını değiştirmek) istemiyorum. Kodu (playpen link):İki vektörü tüketerek yeni bir vektör oluşturmanın iyi bir yolu nedir?

fn main() { 
    let arg1 = vec![1, 2, 3]; 
    let arg2 = vec![4, 5, 6]; 
    let desired = consume_and_concat(arg1, arg2); 
    assert_eq!(desired, vec![1, 2, 3, 4, 5, 6]); 
} 

fn consume_and_concat(vec1: Vec<i32>, vec2: Vec<i32>) -> Vec<i32> { 
    // something nice here 
} 

Ben Vec s için hiçbir + olduğunu biliyorum. Ruby'de, veya vec1.concat(vec2) veya [vec1, vec2].flatten yapıyorum. Kaybettiğim benzer bir şey var mı?

cevap

8

Sana Burada Extend::extend

fn main() { 
    let mut arg1 = vec![1, 2, 3]; 
    let arg2 = vec![4, 5, 6]; 
    arg1.extend(arg2); 
    assert_eq!(arg1, vec![1, 2, 3, 4, 5, 6]); 
} 

aradığınız düşünüyorum, biz arg1 den ayrılan alanı yeniden edebiliyoruz, ancak arg2 yoluyla ayrılan alan verimli yapılması gereken bir şey yok. Orijinal soruya daha spesifik bir Örnek:

fn main() { 
    let arg1 = vec![1, 2, 3]; 
    let arg2 = vec![4, 5, 6]; 
    let desired = consume_and_concat(arg1, arg2); 
    assert_eq!(desired, vec![1, 2, 3, 4, 5, 6]); 
} 

fn consume_and_concat(mut vec1: Vec<i32>, vec2: Vec<i32>) -> Vec<i32> { 
    vec1.extend(vec2); 
    vec1 
} 
+1

Ah. Arayanın “constume_and_concat (mut arg1, arg2)” olması için 'mut' eklemem gerektiğini düşündüm. Yani sanırım bu sorun değil ... bu 'kendini' geri döndürmez 'kendini' geri döndürmez, böylece zincirlenebilir ve doğrudan geri gönderilebilir ... – carols10cents

+2

Ayrıca (kararsız) ['append'] (http: //doc.rust-lang.org/std/vec/struct.Vec.html#method.append), veri yapılarının (birkaçını) kendi iç değişmezlerinden daha verimli olması için kullanmasına izin verecek şekilde tasarlanmıştır. Vec :: append 'sadece bir' memcpy 'olabilir. – huon

1

Sen biriydi eğer yeniden tahsisi üzerinde biraz tasarruf, buna rağmen değişken olması bunlardan birini gerekmez. Rust'la birlikte, güzel şeylerden biri de onu tüketdiğini söylemek zorunda değilsiniz. Bunu sadece işlev imzasından anlayabilirsiniz. Bir referans almadığı için, bu fonksiyonun sahipliğini aldığı anlamına gelir.

fn main() { 
    let vec1 = vec![1, 2, 3]; 
    let vec2 = vec![4, 5, 6]; 
    let concatenated_vecs = consume_and_concat(vec1, vec2); 
    for num in concatenated_vecs { 
     println!("{}", num); 
    } 
} 

fn consume_and_concat(vec1: Vec<i32>, vec2: Vec<i32>) -> Vec<i32> { 
    let mut result : Vec<i32> = vec![]; 
    result.extend(vec1); 
    result.extend(vec2); 
    result 
} 
+1

Bu cevabın, vec1'in tahsis edilmiş alanını attığınız için daha az zarif olduğunu düşünüyorum, * zorlama * bu içeriklerin yeniden tahsisi ve kopyası. – Shepmaster

+0

Evet, sahipliğini ve tüketimini anlıyorum.'(Vec1: Vec , vec2: Vec ) -> Vec 've' (vec1: & Vec , vec2: & Vec değil) işlev imzası ile çözümler aradığımı açıklığa kavuşturmak için bu ayrıntıları ekledim) -> Vec '. – carols10cents

+0

@Shepmaster Katılıyorum. İstenen fonksiyon imzasını eşleştirmek için bu şekilde yazdım. – skyler

4
ben imzasında bir argümanı mut işaretleme gereksiz olduğunu işaret etmek istiyorum

; Bu sadece bir kısayol. Böylece

, biz imzayı değiştirmeden istenilen sonucu elde edebilirsiniz:

fn consume_and_concat(vec1: Vec<i32>, vec2: Vec<i32>) -> Vec<i32> { 
    let mut vec1 = vec1; 
    vec1.extend(vec2); 
    vec1 
} 

Ve vec1 iç tampon yeniden çünkü ikisinin (daha iyi verimlilik için, kontrol kapasitesi o alır gibi yaklaşık olarak verimlidirvec1 ve vec2, daha iyi sonuçlara yol açabilir). Tabii

kısayol:

fn consume_and_concat(mut vec1: Vec<i32>, vec2: Vec<i32>) -> Vec<i32> { 
    vec1.extend(vec2); 
    vec1 
} 

zaten fark, hem de daha kısa ve, vec1 böylece mut onun argümanının türünü değişmez ve gerçeği nasıl değişmez olduğu argümanlar geçmek.

+0

"İmzadaki bir argümanı işaretlemenin gereksiz olduğunu, sadece bir kısayol olduğunu belirtmek isterim." → Bunun nedeni, mutabilitenin, sahip olunan nesneler değil, yığın yerinin bir özelliğidir. Başka bir yere taşındığında, sahip olunan veriler değişebilir hale gelebilir. – Veedrac

+1

Son zamanlarda bana işaret edilen bir şey, işlev argümanındaki "mut" anahtar sözcüğünün pasdoc'ta görünmemesidir, bu yüzden gerçekten bir iç uygulama detayıdır. Bunu öğrendiğimde, onu kullanmak daha muhtemel. – Shepmaster

+0

@Shepmaster: Oh güzel! Bunu duyurduğunuz için teşekkürler! –

İlgili konular