#Kotlin# 一年の使用報告 - 函數式思想

前言

這是「一年の使用報告」系列的第二篇,上一篇可點擊 一年の使用報告 - 類型設計 查看。

正文

關於函數式思想還可以拉上 C# 來討論。C# 大體上和 Java 蠻相似的,它出現的動機也是為了和 Java 抗衡,但很可惜 .Net 的跨平台化並不像 Java 那樣迅速而可靠,目前看來雖然微軟已經在加快腳步,但明顯已經錯失了大多機會。

C# 在 v3.0 就已經開始支持 Lambda 語法了,而 Java 直到 Java 8 才開始支持 Lambda,可以看出雖然一開始大量借鑒了 Java 的思想,但在之後的發展上 C# 是超前於 Java 的。而作為現代編程語言的 Kotlin 對比起兩位前輩來說要顯得更為前衛些,在剛出生時已經融入了函數式、DSL、類型推導等特性。對比下三個語言的 Lambda 寫法:

// Java 8na.listen(context, e -> handler(e));nn// C#na.Listen(context, e => handler(e));nn// Kotlinna.listen(context) { e -> handler(e) }n

個人比較喜歡 Kotlin 的寫法,作為方法最後一位參數的 Lambda 表達式可以直接寫在括弧後,如果只有一位參數的話可以直接省略括弧不寫。

而 Kotlin 在高階函數的聲明上也比 Java,C# 要方便得多,支持形如 (Int)->Int 的 函數類型

// Java 中的高階函數(介面表達)npublic interface Test {n int run(int a);n}npublic void doTest(Test test, int a) {n test.run(a);n}nn// C# 中的高階函數(委託表達)npublic void DoTest(Func<int, int> test, int a)n{n test(a);n}nn// Kotlin 中的高階函數(函數類型表達)nfun doTest(test: (Int)->Int, a: Int) {n test(a)n}n

傳統命令式語言的代碼大都由 表達式控制語句 組成,C# 和 Java 也在此類之中。

// Java 的條件語句nint a;nif (b > 0) {n a = b;n} else {n a = c;n}n

而函數式語言的區別在於函數式語言中的 只有表達式,if else 等被納入多元運算符。Kotlin 也吸收了這種思想,把 if else、when 等作為多元運算符。可以看出 Kotlin 比 Java 和 C# 更接近函數式思想。

// Kotlin 的 if else 表達式nval a = if (b > 0) b else cnn// Kotlin 的 when 表達式nval t = when (x) {n 0, 1 -> truen else -> falsen}n

另外,Kotlin 中的 Delegated Properties(例如 Lazy Delegate)也是函數式思想的表現,它能委託對變數的讀寫操作。例如下面的語句,只有在變數 a 第一次被訪問時才計算結果。

// Kotlin 中的 lazy 代理nval a = lazy { 10 + 11 }n

在函數式語言中,通常還提供了 對 Collection 進行操作的高階函數集(map、filter 之類的方法)。C# 有 LINQ,而 Java 和 Kotlin 有 Streams。

// Kotlin 中的 Streams 介面n(1..10).asSequence().filter { n it > 5n}.forEach {n System.out.print(it)n}n

但要知道 Java 8 才有 Streams 介面,所以目前想在 Android 開發中用上 Streams 介面的最方便的方式依然是使用 Kotlin。

Update:感謝 @林育斌 的提醒,已將最後一個例子改為和 Java 中的 Streams 更相似的 Sequence 實現(惰性計算)。關於 Iterable 和 Sequence 之間的區別可以查看這裡:StackOverflow。Sequence 和 Iterable 具體的取捨需要看使用場景。

推薦閱讀:

Kotlin 讓使用 Android API 變得輕鬆
編程雜談(一) - 英文是很重要的
#Kotlin# 小心 Rx 的生命周期

TAG:Android开发 | Kotlin |