簡體   English   中英

Rust書籍的Patterns部分中的匹配陰影示例非常令人困惑

[英]Match shadowing example in the Patterns section of the Rust book is very perplexing

在學習Rust時,我在正式的Rust書中遇到了以下內容

模式存在一個缺陷:就像引入新綁定的任何東西一樣,它們會引入陰影。 例如:

 let x = 'x'; let c = 'c'; match c { x => println!("x: {} c: {}", x, c), } println!("x: {}", x) 

這打印:

 x: cc: c x: x 

換句話說, x =>匹配模式並引入一個名為x的新綁定,它位於匹配臂的范圍內。 因為我們已經有一個名為x的綁定,所以這個新的x影響它。

我不明白兩件事:

  1. 為什么比賽成功?
    不應該cx的不同值導致失敗嗎?
  2. 匹配臂x綁定如何設置為'c'
    這是不知何故println!的回歸println! 表達?

關於match是什么有一個根本的誤解。

模式匹配不是關於值的匹配,而是關於模式的匹配,顧名思義。 為了方便和安全,它還允許將名稱綁定到匹配模式的內部:

match some_option {
    Some(x) => println!("Some({})", x),
    None    => println!("None"),
}

為了方便起見, match被延伸針對文本 (積分或布爾值),我認為在你的困惑的根特異性匹配時匹配的

為什么? 因為match必須是詳盡無遺的

match表達式是存在的,所以編譯器可以保證你處理所有可能性; 檢查你處理所有模式是很容易的,因為它們在編譯器的控制下,檢查你是否在存在自定義相等運算符時處理所有值。


在match子句中僅使用名稱時,您將創建一個無可辯駁的模式 :永遠不會失敗的模式。 在這種情況下,匹配的整個值綁定到此名稱。

您可以通過在之后添加第二個匹配子句來展示這一點,編譯器將警告后一個綁定無法訪問:

fn main() {
    let x = 42;
    match x {
        name => println!("{}", name),
        _    => println!("Other"),
    };
}

<anon>:6:5: 6:6 error: unreachable pattern [E0001]
<anon>:6         _    => println!("Other"),
                 ^

結合陰影規則,特別允許通過重用其名稱來綁定另一個值來隱藏作用域中的綁定,您將獲得以下示例:

  • match臂內, x綁定到'c'的值
  • 在arm之后,范圍中唯一的x是綁定到值'x'的原始'x'

你的兩點是由同一根問題引起的。 巧合的是,這部分存在的原因是指出你問的問題! 我擔心我基本上會用不同的詞語反復出現這本書的內容。

看看這個樣本:

match some_variable {
    a_name => {},
}

在這種情況下,匹配臂將始終成功 無論some_variable中的值some_variable ,它總是綁定到匹配arm中的名稱a_name 首先獲得此部分非常重要 - 綁定變量的名稱與match之外的任何內容無關。

現在我們轉向你的例子:

match c {
    x => println!("x: {} c: {}", x, c),
}

完全相同的邏輯適用。 匹配臂始終匹配,並且無論c的值如何,它將始終綁定到手臂內的名稱x

來自外部范圍的x (在這種情況下為'x' )在模式匹配中沒有任何影響。


如果要使用x的值來控制模式匹配,可以使用匹配保護

match c {
    a if a == x => println!("yep"),
    _ => println!("nope"),
}

請注意,在匹配保護中( if a == x ),變量綁定ax將返回到可以測試的正常變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM