Pattern Matching là việc kiểm tra xem trong một chuỗi hay cấu trúc dữ liệu có chứa một thành phần nào đó hay không. Trong Swift, Pattern Matching được thực hiện qua câu lệnh case let
với nhiều kiểu cấu trúc dữ liệu khác nhau.
Enums
Pattern Matching cực kỳ hiệu quả khi sử dụng với enums:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | enum State<span class="token operator"><</span>Data<span class="token operator">></span> <span class="token punctuation">{</span> case loading case loaded<span class="token punctuation">(</span>Data<span class="token punctuation">)</span> case failed<span class="token punctuation">(</span>Error<span class="token punctuation">)</span> <span class="token punctuation">}</span> switch state <span class="token punctuation">{</span> case <span class="token punctuation">.</span>loading<span class="token punctuation">:</span> renderLoading<span class="token punctuation">(</span><span class="token punctuation">)</span> case let <span class="token punctuation">.</span>loaded<span class="token punctuation">(</span>shows<span class="token punctuation">)</span> where shows<span class="token punctuation">.</span>isEmpty<span class="token punctuation">:</span> renderEmptyView<span class="token punctuation">(</span><span class="token punctuation">)</span> case let <span class="token punctuation">.</span>loaded<span class="token punctuation">(</span>shows<span class="token punctuation">)</span><span class="token punctuation">:</span> render<span class="token punctuation">(</span>shows<span class="token punctuation">)</span> case let <span class="token punctuation">.</span>failed<span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">:</span> render<span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Khi sử dụng câu lệnh switch
đối với enums có giá trị đính kèm (associated values), có thể dùng câu lệnh case let
để kiểm tra trường hợp và gán giá trị cho một biến. Hơn nữa, có thể lọc giá trị đính kèm thông qua câu lệnh where
.
Optionals
Bản chất của Optional trong Swift là enum có hai trường hợp, vì vậy sử dụng case let đối với optional tương tự như đối với enum.
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">let</span> value<span class="token punctuation">:</span> <span class="token builtin">Int</span><span class="token operator">?</span> <span class="token operator">=</span> <span class="token number">10</span> <span class="token keyword">switch</span> value <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token keyword">let</span> value<span class="token operator">?</span> <span class="token keyword">where</span> value <span class="token operator">></span> <span class="token number">10</span><span class="token punctuation">:</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">"greater than ten"</span><span class="token punctuation">)</span> <span class="token keyword">case</span> <span class="token keyword">let</span> <span class="token punctuation">.</span><span class="token function">some</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token function">print</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token keyword">case</span> <span class="token punctuation">.</span><span class="token keyword">none</span><span class="token punctuation">:</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">"none"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Trong trường hợp .some(value)
, có thể viết dưới dạng value?
.
Tuples
Pattern Matching cũng có thể được sử dụng hiệu quả trên cấu trúc dữ liệu tuple.
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">let</span> auth <span class="token operator">=</span> <span class="token punctuation">(</span>username<span class="token punctuation">:</span> <span class="token string">"majid"</span><span class="token punctuation">,</span> password<span class="token punctuation">:</span> <span class="token string">"veryStrongPassword"</span><span class="token punctuation">)</span> <span class="token keyword">switch</span> auth <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token punctuation">(</span><span class="token string">"admin"</span><span class="token punctuation">,</span> <span class="token string">"admin"</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token function">renderAdmin</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">case</span> <span class="token keyword">let</span> <span class="token punctuation">(</span><span class="token number">_</span><span class="token punctuation">,</span> password<span class="token punctuation">)</span> <span class="token keyword">where</span> password<span class="token punctuation">.</span><span class="token builtin">count</span> <span class="token operator"><</span> <span class="token number">6</span><span class="token punctuation">:</span> <span class="token function">renderShortPasswordMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">case</span> <span class="token keyword">let</span> <span class="token punctuation">(</span>username<span class="token punctuation">,</span> password<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token function">renderUserProfile</span><span class="token punctuation">(</span>username<span class="token punctuation">,</span> password<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Câu lệnh điều kiện
case let
cũng có thể sử dụng lồng ghép với các câu lệnh điều kiện:
1 2 3 4 | <span class="token keyword">if</span> <span class="token keyword">case</span> <span class="token keyword">let</span> <span class="token punctuation">.</span><span class="token function">loaded</span><span class="token punctuation">(</span>shows<span class="token punctuation">)</span> <span class="token operator">=</span> state<span class="token punctuation">,</span> shows<span class="token punctuation">.</span>isEmpty <span class="token punctuation">{</span> <span class="token function">renderEmptyView</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> |
, hoặc:
1 2 3 4 | guard <span class="token keyword">case</span> <span class="token keyword">let</span> <span class="token punctuation">.</span><span class="token function">loaded</span><span class="token punctuation">(</span>shows<span class="token punctuation">)</span> <span class="token operator">=</span> state<span class="token punctuation">,</span> shows<span class="token punctuation">.</span>isEmpty <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Do something here</span> <span class="token punctuation">}</span> |
Câu lệnh lặp
Ngoài sử dụng trong các cấu trúc rẽ nhánh, có thể sử dụng case let
trong cả các vòng lặp:
1 2 3 4 5 | <span class="token keyword">let</span> stateHistory<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token builtin">State</span><span class="token operator"><</span><span class="token punctuation">[</span><span class="token builtin">Show</span><span class="token punctuation">]</span><span class="token operator">></span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">.</span><span class="token function">loaded</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">.</span>loading<span class="token punctuation">]</span> <span class="token keyword">for</span> <span class="token keyword">case</span> <span class="token keyword">let</span> <span class="token punctuation">.</span><span class="token function">loaded</span><span class="token punctuation">(</span>shows<span class="token punctuation">)</span> <span class="token keyword">in</span> stateHistory <span class="token keyword">where</span> shows<span class="token punctuation">.</span><span class="token builtin">count</span> <span class="token operator">></span> <span class="token number">2</span> <span class="token punctuation">{</span> <span class="token comment">// Do something here</span> <span class="token punctuation">}</span> |
Tài liệu tham khảo
https://swiftwithmajid.com/2019/02/06/pattern-matching-with-case-let/