iT邦幫忙

2022 iThome 鐵人賽

DAY 4
0

第一次聽到Pattern,我以為是設計模式,難以理解為什麼都是pattern好像在講兩件事。這邊的模式意謂資料的型態,FP的函數需要關注的是輸入的資料格式,然後用適當的方法處裡成結果,以昨天介紹的Option為例就是一種可為空的資料格式,再看一下程式片段

public static Option Map<TSource, TResult>(this Option source, Func<TSource, TResult> operate)
{
    return source switch
    {
        None => source,
        Some<TSource> { Data: var sourceData } =>
													Option.Some(operate(sourceData)),
        _ => throw new ArgumentException()
    };
}

如果資料的型態為None,就會回傳None型態的結果,如果是Some,就須將Some這個容器內部的資料拿出來做處裡。函數式程式設計為了方便資料處裡,發展出了模式比對,把關注點放在資料的形狀上,C#7以後加入了很多的語法糖,如果從物件導向的觀點其實不太能理解這些模式要怎麼應用,接下來會一一介紹。

宣告模式

用於判斷某個類型是否相容於另一個類型,如果相容則同時做轉型

int? number = null;
if (number is int message) Console.WriteLine(message);
//相當於
int? number = null;
if (number != null) Console.WriteLine(number.Value);

var 模式與屬性模式

這邊可以回來看最上面的switch expression,其實就是宣告模式搭配var與屬性模式的用法,switch expression可以視為早期switch-case的變形,但這種寫法其實是函數式設計的風格,每一個case其實是省略is關鍵字的宣告,而透過var拿出Option裡面存儲的資料,如果對應的資料是某個類別的屬性,就可以針對該屬性取值,另外要注意的是,使用var的話會相容null,而使用明確宣告像是int或是string的話,遇到null判斷的結果則為否。

關聯式模式、邏輯模式、捨棄模式

static string Classify(double measurement) => measurement switch
{
    < -4.0 => "Too low",
    > 10.0 and <20.0 => "little high",
    double.NaN => "Unknown",
    _ => "Acceptable",
};

C#也支援< -4.0 這樣的判斷比對(關聯式),並且利用 notorand 連接陳述式(邏輯),最後的_則表示不在意這個值(捨棄)

位置模式與解構

var point = new Point { X = 10, Y = 60 };

var (x, y) = point;

其實也可以用屬性的位置取值,將類別成員解構

清單模式

這個功能預計在C#11的時候推出,對array跟list有更方便的操作,終於把

var array = new int[] { 1, 2, 3, 4, 5, 6 };
array is [var x, ..var y];
// x = 1
// y = [2,3,4,5,6]

var range = 1..3;
array is [var a, range, ..var b];
// a = 1
// b = [5,6]

第一次看到這個的時候可能覺得莫名其妙,但是這個功能對函數式風格真的超級好用阿!

小結

今天簡單介紹了C#中的pattern match語法,可以參考微軟文件有各種範例。如果單純把這些功能當成語法糖,其實使用起來有點雞肋,因為物件導向的設計比較少會遇到需要對類別做解構的場景,會比較專注於物件本事具有的行為,並且將資料封裝在物件內部,而函數式的設計幾乎是直接將資料結構暴露在外面,然後用解構的語法取出所需的資料,這樣的角度思考可能比較能夠體會pattern match,明天預計再次回到map方法然後介紹高階函數,希望能夠講到IEnumerable與linq。


上一篇
Day3. Option
下一篇
Day5. Higher Order Function
系列文
Functional Programming with C#30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言