2015-08-22 24 views
6

jenerik API'leri inşa etmek Yineleyici özelliği kullanırım ama ben aslında sert toplama türlerine karşı ancak bunun yerine yineleyicinızı karşı değil benim yöntemlerini tasarım nasıl merak ediyorum. Bu yöntemi düşünün. Ben HashSet veya HashMap bir o kullanmak istiyorsanıznasıl ağaçlar için orman görmeyebilir

pub fn print_strings(strings: Vec<String>) { 
    for val in strings.iter() { 
     println!("{}", val); 
    } 
} 

Açıkçası bu kısa düşüyor.

use std::collections::*; 

fn main() { 
    let strings = vec!("Foo", "Bar"); 

    let mut more_strings = HashMap::new(); 
    more_strings.insert("foo", "bar"); 
    more_strings.insert("bar", "foo"); 

    print_strings(&strings.iter()); 
    print_strings(&more_strings.values()) 
} 

fn print_strings(strings: &Iterator<Item=&str>) { 
    for val in strings { 
     println!("{}", val); 
    } 
} 

Çocuk Parkı (aynı zamanda uzun derleyici hatası görmek için)

http://is.gd/EYIK11

Maalesef bu ya hile yapmak gibi görünmüyor:

Yani, bu çalıştı. Neyi kaçırıyorum?

+0

hata mesajı belirtin. Uygulamanızın nesi yanlış olduğunu size söyler.Sahip olduğunuz yineleyici için 'Iterator :: Item' türünün ne olduğunu gözden geçirmek isteyebilirsiniz. – Shepmaster

+0

Bunun çok uzun olduğu için iyi bir fikir olduğunu sanmıyorum. Tüm derleyici hata çıktısını görmek için oyun parkı bağlantısını tıklayabilirsiniz. – Christoph

+0

'Vec ' 'da' .iter() 'yi çağırdığınızda, bir' Iterator 'alırsınız. Yani, 'Vec <&str>' 'da' .iter() 'yi çağırdığınızda, bir' Iterator 'değil, bir' Iterator 'olsun. Iterator için '.cloned()' metoduna bakmalısınız, probleminizi çözmenize yardımcı olmalıdır. – Adrian

cevap

7

Daha da iyisi, (iyileştirme için tebrikler Shepmaster.)

fn print_strings<Iterable>(strings: Iterable) 
    where Iterable: IntoIterator, 
      Iterable::Item: AsRef<str> 
{ 
    for val in strings { 
     println!("{}", val.as_ref()); 
    } 
} 

yapabilirsiniz

Bu dinamik sevk veya beton yineleyici ya için &mut Iterator s ile bu çağrı anlamına gelir Statik sevk için koleksiyon türleri. Ayrıca, yineleyici tipi, &str, &&str ve hatta String'u içeren, ancak bunlarla sınırlı olmamak üzere &str'a dönüştürülebilen herhangi bir şey olabilir.

print_strings(&strings); 
print_strings(strings.iter().map(|s| s.to_owned())); 
print_strings(vec![&&&&"xyz"]); 
print_strings(strings); 
print_strings(more_strings.values()); 
4

Bir Vec<T> numaralı telefondan .iter() numaralı telefonu aradığınızda, bir Iterator<Item=&T> alırsınız. Bu nedenle, Vec<&str> numaralı telefondan .iter()'u aradığınızda, Iterator<Item=&str> değil Iterator<Item=&&str> olsun. Iterator için .cloned() yöntemine bakmalısınız, sorununuzu çözmenize yardımcı olmalıdır.

Ayrıca, bir yineleyici boyunca yineleme için, siz (yineleyici sahibi veya buna bir değişken referansı olarak) bunu mutasyona muktedir gerektiğini unutmayın. Bu yüzden, sadece değişmez bir referansa sahip olmak, faydasızdır. Yineleyici değerini referans olarak iletmekten ziyade print_strings içine taşımanızı öneririm. Bunun için özellik nesneleri kullanmak istiyorsanız, bunu Box kullanarak yapabilirsiniz, ancak print_strings genel bir işlev yapmak daha kolay olabilir.

4

playpen
Yani ilk şey Iterator<Item=&str> bekliyorsanız olduğunu, ama aslında Iterator<Item=&&str> bu.
Sonra, .iter()'u aramaya çalışıyorsunuz, ancak Iterator bu yönteme sahip değil. Sadece (for döngü yani IntoIterator uygulayan, bir şeye ihtiyacı ve &mut Iterator o şeydir) .iter() çağrıyı çıkarıp almayı (ve OFC gönderme) çalışma for döngü elde etmek için &mut Iterator<...> olabilir.
Yaşamları ekleyin ve hepiniz ayarlandınız!
Ayrıca, statik gönderim kullanmayı öneririm. Sağladığım örnekte görebilirsiniz.

+0

Tamam, o oyun parkı mükemmel bir şekilde temizler. Statik sevkıyatla ilgili olarak, örnek için bazı tuş vuruşlarını kaydediyordum: P – Christoph

İlgili konular