2016-01-22 18 views

cevap

15

itibaren The Rust Programming Language bölüm `type` Aliases başlıklı: Örneğin, kartım oyunda ben F # bir sıra değeri tanımladıktan

type anahtar kelime başka türde bir takma ad bildirmek sağlar:

type Name = String; 
gerçek bir tip sanki daha sonra bu türünü kullanabilirsiniz

:

type Name = String; 
let x: Name = "Hello".to_string(); 

Okuması gereken daha çok şey var ama bu soruya cevap veriyor. başyazısında biraz itibariyle


, bir tür takma insanlar bunları kullanmak yerlerde bir sürü büyük bir uyum olduğunu düşünmüyorum. Rank türünüzün bir kart destesiyle ilgili bir şey olduğunu varsayarsak, enum veya newtype'u öneririm. Kartların tipik güverte saçmadır

let rank: Rank = 100; 

: nedeni bir tür takma adı ile böyle bir şey yapabiliyor olmasıdır. Bir enum sınırlı bir kümedir. Bu geçersiz bir Rank oluşturmak asla şu anlama gelir:

enum Rank { 
    One, Two, Three, Four, Five, 
    Six, Seven, Eight, Nine, Ten, 
    Jack, Queen, King, Ace, 
} 

impl Rank { 
    fn from_value(v: u8) -> Result<Rank,()> { 
     let r = match v { 
      1 => One, 
      2 => Two, 
      // ... 
      _ => return Err(()), 
     }; 
     Ok(r) 
    } 

    fn value(&self) -> u8 { 
     match *self { 
      One => 1, 
      Two => 2, 
      // ... 
     } 
    } 
} 

A newtype sadece sarıcı türüdür. Sarılmış tiple karşılaştırıldığında fazladan alan tüketmez, yalnızca geçerli değerleri kısıtlayabilen yöntemleri uygulamanızı sağlayan gerçek bir yeni tür sağlar. Bu geçersiz değerler oluşturmak mümkündür, ancak sadece kendi kodu içinde, tüm istemci kodu:

struct Rank(u8); 

impl Rank { 
    fn from_value(v: u8) -> Result<Rank,()> { 
     if v >= 1 && v <= 14 { 
      Ok(Rank(v)) 
     } else { 
      Err(()) 
     } 
    } 

    fn value(&self) -> u8 { 
     self.0 
    } 
} 

Ben türlerinin hızlı tutucu olarak tip takma adları kullanma eğilimindedir. Yukarıdaki örnekler yazarken, aslında yazdı:

type Error =(); 

Ve Result<Rank, Error> döndü ama sonra o kafa karıştırıcı olacağını düşündük. :-)

Onları kullandığım diğer durum, saklamak istemediğim daha büyük bir tür kısaltmaktır. Bu, see in the standard library olan yineleyiciler veya Result s türleriyle olur. Şunlar gibi:

type CardResult<T> = Result<T, Error>; 

fn foo() -> CardResult<String> { 
    // .. 
} 
+1

Hızlı ve ayrıntılı yanıt için teşekkürler! Normalde değerlerimi standart güverte değerleriyle sınırlamak için enums kullanarak sizinle aynı fikirdeyim. Ancak, benim durumumda, "kart" terimini jenerik olarak kullanıyorum ve oyun kartını kullanmam, bu yüzden belirtilmemiş bir değer sıralamasına ihtiyacım var. Basit bir ikame ve eğer ek kısıtlamalar/mantık dayatmak istersem yeni bir tip kullanmak istiyorsam, bir tür takma ad kullanmam gerektiğini doğru mu anlıyorum? –

+0

@ErikUggeldahl evet, kulağa doğru geliyor. Yeni bir tür ek kısıtlamalara veya mantığa izin verirken, takma ad sadece aynı şey için başka bir addır. – Shepmaster

+2

@ErikUggeldahl sadece değerleri kısıtlamak değil. Bir takma ad, herhangi bir ek tip güvenlik sağlamaz çünkü ...yeni tip, ama aynı tür için başka bir isim. "Rank/5" 'i hesaplayabilmeniz ya da 'Rank' 'u8' alan bir işleve geçebilmeniz sizin için anlamlı mıdır? Bir tür takma ad bunu yapmanıza izin verdiğinden ('Rank' * * a' u8' olduğundan). Normalde, çok uzun ve karmaşık bir türdeyken ve daha kısa bir ifadeyle başvurmak istediğinizde, Rust'taki yazı tipi takma adlarını kullanmanız kolaylık sağlamak içindir (ancak diğer ad *, * türü ve bunun yerine her yerde kullanılmalıdır) –

İlgili konular