2016-01-22 39 views

回答

15

The Rust Programming Language標題爲`type` Aliases

type關鍵字可以聲明另一個類型的別名:

type Name = String; 

,就好像它是一個真正的類型,你可以使用這個類型:

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

還有更多的你應該閱讀,但這回答了這個問題。


作爲一種編輯方式,我不認爲類型別名很適合人們使用它們的很多地方。假設你的Rank類型代表了一副撲克牌,我建議你要麼是enum要麼是newtype。原因在於,對於類型別名,您可以這樣做:

let rank: Rank = 100; 

這對於典型的一副牌是無意義的。枚舉是一個受限制的集合。這意味着你不能創建一個無效Rank

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, 
      // ... 
     } 
    } 
} 

一個NEWTYPE只是一個包裝類型。與包裝類型相比,它不佔用額外的空間,它只是提供了一種實際的新類型,可讓您實現可限制爲有效值的方法。它可以創建無效值,但僅限於你自己的代碼,不是所有的客戶端代碼:

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 
    } 
} 

我傾向於使用類型別名爲類型的快速佔位符。在寫上面的例子,其實我寫的:

type Error =(); 

,並返回一個Result<Rank, Error>,但後來認爲這將是混亂的。 :-)

我使用它們的另一種情況是縮短我不想隱藏的較大類型。這種情況發生在類似迭代器或Result的情況下,您可以使用see in the standard library。例如:

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

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

感謝您的快速和詳細的回覆!通常我非常同意你使用枚舉將我的值限制爲標準套牌值。不過,就我而言,我一般使用「卡」一詞,而不是紙牌,所以我需要一個未指定值的等級。 我是否正確理解我應該使用類型別名,如果我想要簡單替換,以及如果我想要施加其他限制/邏輯,則使用新類型? –

+0

@ErikUggeldahl是的,這聽起來正確。新類型允許額外的限制或邏輯,而別名​​就是這樣,另一個名字就是同一個名字。 – Shepmaster

+2

@ErikUggeldahl它不僅限制了值。別名不提供額外的類型安全性,因爲它不是...新類型,但同一類型的另一個名稱。你能夠計算一個'Rank/5'或將一個'Rank'傳遞給一個需要'u8'的函數嗎?因爲類型別名允許你這樣做(因爲'Rank' *是* u8')。你通常在Rust中使用類型別名是爲了方便,當你有一個非常長和複雜的類型並且想要更簡潔地引用它時(但別名*是*類型並且應該用來代替它到處) –

相關問題