4-模式匹配
4-模式匹配
匹配運算子
模式匹配
pin運算子
本章起教程進入不那麼基礎的階段,開始涉及函數語言程式設計概念。
在Elixir中,=
運算子實際上是一個匹配運算子。
本章將講解如何使用=
運算子來對資料結構進行模式匹配。最後本章還會講解pin運算子^
,用來訪問某變數之前繫結的值。
4.1-匹配運算子
我們已經多次使用=符號進行變數的賦值操作:
iex> x = 1
1
iex> x
1
在Elixir中,=
其實稱為匹配運算子。下面來學習這樣的概念:
iex> 1 = x
1
iex> 2 = x
** (MatchError) no match of right hand side value: 1
注意1 = x
是一個合法的表示式。由於前面給x賦值為1,左右相同,所以它匹配成功了。而兩側不匹配的時候,MatchError將被丟擲。
變數只有在匹配操作符=
的左側時才被賦值:
iex> 1 = unknown
** (RuntimeError) undefined function: unknown/0
錯誤原因是unknown變數沒有被賦過值,Elixir猜你想呼叫一個名叫unknown/0的函式,但是找不到這樣的函式。
4.2-模式匹配
匹配運算子不光可以匹配簡單數值,還能用來解構複雜的資料型別。
例如,我們在元組上使用模式匹配:
iex> {a, b, c} = {:hello, "world", 42}
{:hello, "world", 42}
iex> a
:hello
iex> b
"world"
在兩端不匹配的情況下,模式匹配會失敗。比方說,匹配兩端的元組不一樣長:
iex> {a, b, c} = {:hello, "world"}
** (MatchError) no match of right hand side value: {:hello, "world"}
或者兩端不是一個型別:
iex> {a, b, c} = [:hello, "world", "!"]
** (MatchError) no match of right hand side value: [:hello, "world", "!"]
有趣的是,我們可以匹配特定值。下面例子中匹配的左端當且僅當右端是個元組,且第一個元素是原子:ok。
iex> {:ok, result} = {:ok, 13}
{:ok, 13}
iex> result
13
iex> {:ok, result} = {:error, :oops}
** (MatchError) no match of right hand side value: {:error, :oops}
用在列表上:
iex> [a, b, c] = [1, 2, 3]
[1, 2, 3]
iex> a
1
列表支援匹配自己的head和tail(這相當於同時呼叫hd/1和tl/1,給head和tail賦值):
iex> [head | tail] = [1, 2, 3]
[1, 2, 3]
iex> head
1
iex> tail
[2, 3]
同hd/1
和tl/1
函式一樣,以上程式碼不能對空列表使用:
iex> [h|t] = []
** (MatchError) no match of right hand side value: []
[head|tail]這種形式不光在模式匹配時可以用,還可以用作前置數值:
iex> list = [1, 2, 3]
[1, 2, 3]
iex> [0|list]
[0, 1, 2, 3]
模式匹配使得程式設計師可以容易地解構資料結構(如元組和列表)。在後面我們還會看到,它是Elixir的一個基礎,對其它資料結構同樣適用,比如圖和二進位制。
4.3-pin運算子
在Elixir中,變數可以被重新繫結:
iex> x = 1
1
iex> x = 2
2
如果你不想這樣,可以使用pin運算子(^)。加上了pin運算子的變數,在匹配時使用的值是匹配前就賦予的值:
iex> x = 1
1
iex> ^x = 2
** (MatchError) no match of right hand side value: 2
iex> {x, ^x} = {2, 1}
{2, 1}
iex> x
2
注意如果一個變數在匹配中被引用超過一次,所有的引用都應該繫結同一個模式:
iex> {x, x} = {1, 1}
1
iex> {x, x} = {1, 2}
** (MatchError) no match of right hand side value: {1, 2}
有些時候,你並不在意模式裡的一些值。通常你就可以把它們繫結到特殊的變數“_”上。例如,如果你只想要某列表的head,而不要tail值。你可以這麼做:
iex> [h | _] = [1, 2, 3]
[1, 2, 3]
iex> h
1
變數“_”特殊之處在於它不能被讀。嘗試讀取它會報“未繫結的變數”錯誤:
iex> _
** (CompileError) iex:1: unbound variable _
儘管模式匹配可以讓我們建立功能強大的結構,但是它的作用被限制了。 比如,你不能讓函式呼叫作為匹配的左端。下面例子就是非法的:
iex> length([1,[2],3]) = 3
** (CompileError) iex:1: illegal pattern
相關文章
- Scala模式匹配模式
- Rust -- 模式與匹配Rust模式
- C# 模式匹配C#模式
- Swift中的模式匹配Swift模式
- 聊聊 scala 的模式匹配模式
- Glob Patterns匹配模式使用模式
- Scala模式匹配詳解模式
- 字串匹配模式問題字串匹配模式
- MySQL 5.5 模式匹配LIKEMySql模式
- KMP字串模式匹配詳解KMP字串模式
- scala模式匹配詳細解析模式
- PostgreSQL:模式匹配操作符SQL模式
- 模式匹配-KMP演算法模式KMP演算法
- [譯] Swift 中強大的模式匹配Swift模式
- 正規表示式支配匹配模式模式
- KMP模式匹配演算法KMP模式演算法
- [JS高程] 字串模式匹配方法JS字串模式
- 一起學Scala 模式匹配模式
- elixir二進位制模式匹配模式
- 模式匹配與正規表示式模式
- Query Designer中模式匹配排除模式
- AC 自動機——多模式串匹配模式
- 模式匹配kmp演算法(c++)模式KMP演算法C++
- 常用正規表示式匹配模式(java)模式Java
- 第二章:data和模式匹配模式
- C# 7.0 新特性(3): 模式匹配C#模式
- 串(2)--模式匹配演算法模式演算法
- bash 引數替換中的模式匹配模式
- 在匹配模式中玩人機對戰?模式
- Java 17 新特性:switch的模式匹配(Preview)Java模式View
- Rust中用元組模式匹配替代if-elseRust模式
- Egison 3.5.1 釋出,模式匹配程式語言模式
- Mensa是Java的模式匹配開源庫Java模式
- 樸素的模式匹配演算法模式演算法
- C#.Net築基-模式匹配彙總C#模式
- 編寫一個程式實現模式串的各種模式匹配模式
- C# 9.0 新特性之模式匹配簡化C#模式
- js中split之正則運用(模式匹配)JS模式