###導入###
| この記事では主にKotlin関数の使い方と関数型プログラミングについての私の理解の一部を紹介します。 Python と C との比較も行います。
|
Google の父親が Kotlin をゴッドソンとして発表して以来、Kotlin は主要なコミュニティで非常に人気があります。
Kotlin 構文について何も知らない場合は、理解を深めるためにこの記事を読む前に、公式ドキュメントまたは中国語の Web サイト (https://www.kotlincn.net/docs/reference/) を読むことをお勧めします。
以下は、Wikipedia からの関数型プログラミングの定義です:
関数型プログラミング (英語: Functional programming) は、関数型プログラミングとも呼ばれ、コンピューターの操作を数学的な関数計算として扱い、プログラムの状態や簡単に変更できるオブジェクトの使用を避けるプログラミング パラダイムです。関数型プログラミング言語の最も重要な基礎はラムダ計算です。また、ラムダ計算の関数は、関数を入力 (引数) および出力 (出力値) として受け入れることができます。
高階関数の定義は次のとおりです:
数学とコンピューター サイエンスでは、高次関数とは、次の条件の少なくとも 1 つを満たす関数です: 1 つ以上の関数を入力として受け入れ、関数を出力します
関数型プログラミングの最も重要な基礎が高階関数であることを推測するのは難しくありません。つまり、サポート関数は関数を入力 (引数) および出力 (出力値) として受け入れることができます。
Kotlin の第一級市民として、関数は他のオブジェクトと同様に関数の入力および出力として使用できます。これは、Java プログラマーが Kotlin に切り替えるときに最大の変化を感じ、理解するのが最も難しい点です。以前に Python または C 11 を学習したことがあれば、これは簡単かもしれません。そのため、この記事では主に Kotlin 関数と関数型プログラミングを紹介します。
Kotlin 関数
以下は Kotlin での一般的な関数定義です Java とは異なり、関数のパラメータは最後に配置され、戻り値の型は最後に配置されます。関数本体は等号を使用して関数定義に割り当てることができ、関数と変数の同等性もここで確認できます。
リーリー
さらに、Kotlin は関数のデフォルト パラメーター、拡張関数、および中置式もサポートしています。以下は簡単な例です:
リーリー
デフォルトパラメータをサポートする関数は、関数のオーバーロードを軽減できます。
String オブジェクトには、それが文字であるかどうかを判断するメソッドはありません。Java では通常、いくつかの Utils メソッドを定義しますが、Kotlin ではクラス拡張関数を定義できます。
2 番目の例は、Int クラスの拡張関数を定義するもので、拡張関数は中置式として表現され、開発者に同様のキーワードを定義する権利を与えます。
たとえば、次のようなマップ オブジェクトを作成できます:
リーリー
ここでの to は、次のように定義される中置式です:
リーリー
Pair は Map に格納されているオブジェクトなので、次のように作成することもできます
リーリー
Python では、関数が複数の値を返すようにしたい場合は、タプルを返すことができます。Kotlin でも、構造化原理に基づいて同様の関数を実現できます。
リーリー
カスタム オブジェクトが構造化をサポートする方法については、公式ドキュメントを確認してください。マップは構造化をサポートしているため、次のように走査できます:
リーリー
高階関数とラムダ式
「ラムダ式」(ラムダ式)は、匿名関数です。ラムダ式は、数学のラムダ計算に基づいて命名されています。ラムダ抽象化(ラムダ抽象化)に直接対応します。匿名関数です。関数名がありません。関数です。ラムダ式はクロージャを表すことができます (ラムダ式は従来の数学的な意味とは異なることに注意してください)。
Python のラムダ式:
リーリー
C のラムダ:
リーリー
Kotlin のラムダ:
リーリー
Kotlin は、強く型付けされた言語としては比較的シンプルです。
次のようなラムダ式を使用できます:
リーリー
関数のように () を使用して呼び出すことができます。kotlin では演算子をオーバーロードできます。() 演算子は、クラスのオーバーロードされた関数 invoke() に対応します。
次のように変数を定義することもできます:
リーリー
これは通常の変数ではありません。関数を指す必要があり、関数のシグネチャは一貫していなければなりません:
リーリー
この変数はラムダ式、別のラムダ式変数、または通常の関数と等しいことがわかりますが、関数参照を取得するには関数名の前に (::) を追加する必要があります。
これは C の関数ポインターに似ています。ただし、Python では関数名を関数参照として直接使用できます。次に、C 関数ポインターの例を示します:
リーリー
Kotlin に戻ると、次のように、ある関数を別の関数に渡すこともできます。
リーリー
最初のパラメータはリスト、2 番目のパラメータは関数です。目的は、リスト内の要素ごとに 2 番目の関数を 1 回実行することです。それの使い方: ###
リーリー
2 番目のパラメータはラムダ式に直接渡されます。もちろん、関数参照も渡すことができます:
リーリー
結果は上記のコードと同じです。
C で関数ポインタを使用すると、同様の効果が得られます:
リーリー
再び Kotlin に戻ります。関数が入力パラメーターとしてパラメーター リストの最後の関数である場合は、これを実行して中括弧内に直接記述することもできます。
リーリー
これは、Kotlin がドメイン固有言語 (DSL) を簡単に記述できるようにする Gradle 構成ファイルの記述方法に少し似ていますか?
さらに、Kotlin はローカル関数と戻り値としての関数もサポートしています。次のコードを参照してください。
fun main(args: Array) {
val addResult = lateAdd(2, 4)
addResult()
}
//局部函数,函数引用
fun lateAdd(a: Int, b: Int): Function0 {
fun add(): Int {
return a + b
}
return ::add
}
ログイン後にコピー
在lateAdd内部定义了一个局部函数,最后返回了该局部函数的引用,对结果使用()操作符拿到最终的结果,达到延迟计算的目的。
函数作为一级公民当然可以像普通对象一样放进map中,比如下面这样:
val funs = mapOf("sum" to ::sum)
val mapFun = funs["sum"]
if (mapFun != null) {
val result = mapFun(1,2)
println("sum result -> $result")
}
fun sum(a: Int, b: Int): Int {
return a + b
}
ログイン後にコピー
将一个函数引用作为value放进了map中,取出来之后使用()操作符调用,可以简化一些if,else的场景。
基于以上函数式编程的特性,Kotlin可以像RxJava一样很方便的进行相应式编程,比如:
fun printUpperLetter(list: List) {
list
.filter (fun(item):Boolean {
return item.isNotEmpty()
})
.filter { item -> item.isNotBlank()}
.filter {
item ->
if (item.isNullOrEmpty()) {
return@filter false
}
return@filter item.matches(Regex("^[a-z|A-Z]$"))
}
.filter { it.isLetter() }
.map(String::toUpperCase)
.sortedBy { it }
.forEach { print("$it, ") }
println()
}
ログイン後にコピー
上面的代码只是做演示,并无实际意义。具体语法请查看官方文档。
我相信Kotlin作为一种强类型的现代化语言可以在保证稳定性的同时极大地提高开发者的开发效率。