2017-01-11 19 views
6

Bir yapının genel alanının veri türünü eşleştirmeye çalışıyorum ve buna göre tepki veriyorum.Rust'taki veri türü ile nasıl eşleştirilir?

struct foo<T> { 
    zaz: String, 
    bar: T, 
} 

fn main() { 
    let x = foo::<String> { 
     zaz: "Hello".to_string(), 
     bar: "world".to_string(), 
    }; 
    let y = foo::<u32> { 
     zaz: "Hello".to_string(), 
     bar: 5, 
    }; 

    match x.bar { 
     String => println!("It's a string!"), 
     u32 => println!("It's a u32!"), 
     _ => println!("Something else"), 
    }; 

    println!("end of program!"); 
} 

rustc gelen hata mesajı:

error[E0001]: unreachable pattern 
    --> src/main.rs:18:9 
    | 
18 |   u32 => println!("It's a u32!"), 
    |   ^^^ this is an unreachable pattern 
    | 
note: this pattern matches any value 
    --> src/main.rs:17:9 
    | 
17 |   String => println!("It's a string!"), 
    |   ^^^^^^ 

error[E0001]: unreachable pattern 
    --> src/main.rs:19:9 
    | 
19 |   _ => println!("Something else"), 
    |  ^this is an unreachable pattern 
    | 
note: this pattern matches any value 
    --> src/main.rs:17:9 
    | 
17 |   String => println!("It's a string!"), 
    |   ^^^^^^ 
İlkini maç için x içindi istediği Ne

ve y maç için My genel bir fikir (kod derleme değil) böyleydi ikinci olan. Yapmak istediğim şeyden gerçekten emin değilim, ama istenen etkiyi ne elde edecekti?

+0

:) bunu yapma. Bu soruyu yararlı bulabilirsiniz: [Rust yansımayı nasıl uygular?] (Http://stackoverflow.com/q/36416773/1233251) –

+0

Rust, struct, enums ve traits için 'CamelCase'i kullanır. Foo kullanmalısın. – Shepmaster

cevap

8

İdiomatik Çözelti

, foo parametresi T kısıtlayan bir özellik oluşturmak Bu özelliğin ilişkili bir fonksiyonu olarak herhangi bir davranış uygulanması.

Örnek:

trait PrintMe { 
    fn print_me(&self); 
} 

impl PrintMe for String { 
    fn print_me(&self) { println!("I am a string"); } 
} 

struct Foo<T: PrintMe> { 
    zaz: String, 
    bar: T 
} 

fn main() { 
    // ... 
    x.bar.print_me(); 
} 

Bu sürpriz değildir, böylece olası jenerik parametrelerin davranışının tam olarak fark beyan ilkeli genel programlama,.


Kesin Çözüm

Pas olabilir gerçekten sorgu türleri: Her tür ilişkili benzersiz TypeId vardır ve if bir dizi kontrol ile TypeId üzerinde eşleşebilir. Bu tıkalı.

fn print_me<T>(x: &Foo<T>) { 
    if TypeId::of::<T>() == TypeId::of::<String>() { 
     println!("I am a string"); 
    } else // ... 
} 

Ama lütfen ... kısa cevabı "değil derhal kapalı" dır

+0

Teşekkür ederim, Matthieu. Bu işleri temizler. Tasarımımı genel olarak değiştirmem gerektiğini düşünüyorum, "C stili" kodumu koymaya devam ediyorum. Teşekkürler! – Dash83

+0

+1 “bunu yapma” için, ve ben sadece Rust * 'in daha iyi (daha kısa, daha açık, idiyomik ve derleme zamanı kontrol edilen) bir yol olduğunu yazıyor. TypeId :: of 'çekleri. – trentcl

+0

@trentcl: Bağlıdır. “enum” kapalı polimorfizm içindir, “karakter” açık-polimorfizm içindir ... eğer bu mantıklıysa. –