2016-04-28 26 views
3

我不是一個功能程序員。所以我對模式匹配,模式或其他任何東西都不是很熟悉。對我而言,我只理解陳舊的switch聲明的概念。如何用Rust等語言實現匹配?

編譯器如何實現匹配語句?匹配和交換機之間究竟有什麼區別?有一個GNU C99擴展,它可以讓你有一個開關的情況下的範圍,是有之間的差異:

match x { 
    0 ... 9 => ..., 
    _ => ..., 
} 

switch (x) { 
case 0 ... 9: ...; break; 
default: ...; break; 
} 

注意,第二個片段是一個簡單的C開關與此GNU擴展。

回答

4

常量值上的模式匹配可以作爲跳轉表或一系列條件跳轉來實現 - 就像switch語句一樣。允許範圍不會改變這種情況。

Rust枚舉(至少包含成員的枚舉)像標記的聯合一樣實現,即包含標記的結構和包含成員的結構聯合。

enum上的模式匹配然後簡單地轉換爲其標記上的開關(將由模式綁定的變量綁定到union的成員)。因此,像這樣防鏽代碼:

enum Result { 
    SingleResult(i32), 
    TwoResults(i32, i32), 
    Error 
} 

match someResult { 
    Result::SingleResult(res) => f(res), 
    Result::TwoResults(res1, res2) => g(res1, res2), 
    Result::Error => error() 
} 

將轉化爲在同一臺機器代碼(大概)如下面的C代碼:

struct Result { 
    enum { 
    SingleResult, TwoResults, Error 
    } tag; 
    union { 
    struct { 
     int arg1; 
    } singleResult; 
    struct { 
     int arg1; 
     int arg2; 
    } twoResults; 
    } value; 
}; 

switch(someResult.tag) { 
    case SingleResult: { 
    int res = someResult.value.singleResult.arg1; 
    f(res); 
    break; 
    } 
    case TwoResults: { 
    int res1 = someResult.value.twoResults.arg1; 
    int res2 = someResult.value.twoResults.arg2; 
    g(res1, res2); 
    break; 
    } 
    case Error: { 
    error(); 
    break; 
    } 
} 
+0

這非常有意義。謝謝! –

+0

你有任何參考或相關的源代碼來支持? –

+0

@TylerDavis不,但我確實看過生成的代碼進行驗證。 – sepp2k