関数の使用


コトリンは開発者に無条件にクラスを使用するように強制しない.
再利用可能な最小単位がクラスのJavaとは異なり、Cortlinではクラスと個別の関数を再利用できます.

📌 関数の作成


KISS関数


コトリンは関数を定義する際にKISSの原則を守る.
小関数は簡単で、干渉がなく、ミスがないように書くべきです.
関数定義はfunキーで始まります.
関数が非常に短い単一の表現関数である場合、関数定義セクションと関数マスターを、マスターを{}に設定するのではなく=に区別できます.

タイプとタイプの推論を返す


greet()関数は戻りタイプを指定していませんが、文字列を返します.
コトリンはブロック本体のない関数をタイプ推定するからだ.
fun greet() = "Hello"
println(greet())

val message: Int = greet() //ERROR : Type mismatch: inferred type is String but Int was expected
コトリンはコンテキストに基づいてgreet()のリターンをStringと決定した.
greet()の結果をInt型変数messageに割り当てると、エラーマッチングエラーが発生し、エラー結果からStringが戻り型推定であることが判明します.
コトリンの戻りタイプ推定は、関数のボディがブロックではなく単一の式である場合にのみ使用できます.
fun greet(): String = "hello"
もちろん、戻りタイプを明示することもできます.
戻りタイプの前に追加:パラメータリストの後に記入
returnキーワードは単一の式関数であり、本体がブロックでない場合は許可されません.

すべての関数は式です


コトリンは命令ではなく式が好きで、その原則に基づいて、関数は命令ではなく式として扱われるべきだ.
コトリンはJavaのvoidではなくUnitという特殊なタイプを使用しています.
返却可能な内容がない場合はUnitを使用できます.
fun sayHello() = println("Well, Hello")

val message: String =sayHello() //ERROR : Type mismatch: inferred type is Unit but String was expected
Stringタイプ変数にsayHello()の結果を割り当てるとエラーが発生します.
エラー内容を確認した場合、タイプmist matchでsayHelo()の返信タイプがUnitであることを確認できます.

入力

fun sayHello(): Unit = println("Well, Hello")
val message: Unit = sayHello()
println("The result of sayHello is $message")

💻 しゅつりょく

Well, Hello
The result of sayHello is kotlin.Unit
デバイスタイプには、toString()メソッド、equals()メソッド、hashCode()メソッドがあります.
上記のコードの出力内容からprintln()はUnitのtoString()メソッドを内部で呼び出していることがわかる.
UnitのtoString()メソッドはkotlinです.Unitという名前のクラス名のみが返されます.
コトリンでは、すべての関数が有用なコールバックを与えます.
void関数もUnitを返すので、すべての関数を式として使用できます.

パラメータの定義


コトリンは、関数またはメソッドにパラメータのタイプを明記することを要求します.パラメータのタイプは、パラメータ名の後に「区切り」を使用します.
fun greet(name : String) = "Hello $name"
println(greet("Eve")) //Hello Eve
コトリンは、関数またはメソッドパラメータを作成するときに、この調整可能または調整可能なパラメータを選択することを望んでいません.
パラメータをvalまたはvarと断定することはできません.関数またはメソッドでパラメータ値を変更しようとすると、コンパイルエラーが発生します.

ブロック本体で作成された関数


ブロック本体定義関数を使用する場合は、常に戻りタイプを定義する必要があります.
定義しない場合、戻りタイプはUnitと推定されます.
fun max(numbers: IntArray): Int {
    var large = Int.MIN_VALUE
    for (number in numbers) {
        large = if (number > large) number else large
    }
    return large
}
💡注意:=ブロック本体の代わりに使用できません.特定の戻りタイプを指定して=を使用し、{}ブロックボディを使用すると、コンパイラエラーが発生します.
戻りタイプを省略し、単一の式ではなくブロックボディを使用する場合、コトリンはブロックをramda式または匿名関数と見なします.

入力

fun f1() = 2
fun f2() = { 2 }
fun f3(factor: Int) = { n: Int -> n * factor }
println(f1())
println(f2())
println(f2()())
println(f3(2))
println(f3(2)(3))

💻 しゅつりょく

2
() -> kotlin.Int
2
(kotlin.Int) -> kotlin.Int
6
f 1()推定戻りタイプはInt
f 2()パラメータなし、リターンタイプIntのRamda式として導出
f 3()は,Intをパラメータ,Intを戻り型とするRamda式を導いた.
これらのコードは良いコードではありません.
=と{}ブロックボディを同時に使用しないほうがいいことを覚えておいてください.

📌 デフォルトのパラメータと明示的なパラメータ


デフォルトのArgumentによる関数の変更

fun greet(name : String) = "Hello $name"
println(greet("Eve")) //Hello Eve
ハードコーディングgreet()関数に柔軟性を提供する方法は様々である.
✔¥関数に新しいパラメータを追加=>関数を呼び出したコードにエラーが発生します.
✔使用過負荷=>コード重複出現
⭕科特林は基本技術を利用してこれらの問題を簡単に解決する.
fun greet(name: String, msg: String = "Hello"): String = "$msg $name"
println(greet("Eve")) //기존코드도 오류없이 작동
println(greet("Eve", "Howdy"))
greet()を呼び出すコードは、1つのnameパラメータのみを渡すことも、nameとmsgパラメータを同時に渡すこともできます.
fun greet(name: String, msg: String = "Hi ${name.length}"): String = "$msg $name"
println(greet("Scott", "Howdy"))
println(greet("Scott"))
以上のコードは、入力したnameパラメータを使用してmsgのデフォルト値を作成します.
ここでnameとmsgの位置が変わるとエラーが発生します.
msgはnameパラメータを参照しますが、nameは初期化されていません.
このような状況に対応するためには、最後に基本芸術を手配したほうがいい.

明示的なテクノロジーによる読み取り可能性の向上


コードの作成は1回ですが、更新コードは複数回発生するため、コードの可読性が重要です.
fun createPerson(name: String, age: Int = 1, height: Int, weight: Int) {
    println("$name $age $height $weight")
}

createPerson("Jake", 12, 152, 43)
2番目のコードを見るだけでは、各数字が何を意味するかは把握できません.
明示的な規制により、コードの読み取り可能性が向上
createPerson(name = "Jake", age = 12, height = 152, weight = 43)
明確な項目を通して,これらのパラメータが何を意味するかを一気に知ることができる.
createPerson("Jake", age = 12, weight = 152, height = 43)
createPerson("Jake", height = 152, weight = 43)
明示的なアイテムは順番に使用できますが、ageにはデフォルト値があるので、渡す必要はありません.

📌 マルチパラメータと表計算ドキュメント


println()のような関数は、複数のパラメータを受け入れます.コトリンの多重機能は,関数が複数のパラメータを一度に受信する際にタイプセキュリティを提供する機能である.

複数のパラメータ


cottlin関数は多くの球パラメータを受信できるため、max()関数を呼び出し時により柔軟に使用するように変更しましょう.
fun max(vararg numbers: Int): Int {
    var large = Int.MIN_VALUE
    for (number in numbers) {
        large = if (number > large) number else large
    }
    return large
}
二つが変わった
✔パラメータ番号はvarargキーワードとして宣言されています.
✔パラメータタイプをIntraryからIntに変更します.
println(max(1, 6, 3))//6
println(max(1, 6, 3, 9, 4, 12))//12
コードがうまく動く
max()関数は、1つのパラメータのみを処理するように定義されます.ただし、varargを使用すると、1つ以上のパラメータを処理できます.
ただし、varargキーワードは関数の1つのパラメータでのみ使用できます.

入力

fun greetMany(msg: String, vararg names: String) {
    println("$msg ${names.joinToString(", ")}")
}
greetMany("Hello", "Tom", "Jerry", "Spike")

💻 しゅつりょく

Hello Tom, Jerry, Spike
この関数を呼び出すと、最初のパラメータが最初のパラメータに割り当てられ、残りのパラメータがvarargパラメータに渡されます.

入力

fun greetMany(vararg names: String,msg: String) {
    println("$msg ${names.joinToString(", ")}")
}

greetMany("Hello", "Tom", "Jerry", "Spike")//ERROR : No value passed for parameter 'msg'

また、varargパラメータは最後のパラメータとして使用することが望ましい
関数を呼び出すときに、名前のないStringパラメータが複数渡された場合、コンパイラはすべてのパラメータをvarargパラメータと見なします.
💡 最後にvarargを使用する場合は、明示的なパラメータを使用する必要があります.

表計算ドキュメント演算子


max()を再表示すると、関数は複数のパラメータを受信するように定義されますが、配列やリストを直接受信することはできません.この場合spread演算子を使用します
varargeは、パラメータが大量のパラメータを伝達できることを意味します.しかし配列をパラメータに渡すとエラーが発生します.
val values = intArrayOf(1, 21, 3)
println(max(values)) //ERROR :Type mismatch: inferred type is IntArray but Int was expected
内部ではvarargパラメータを配列として使用しますが、cottlinは配列をパラメータとして渡すのが好きではありません.
println(max(values[0], values[1], values[2]))
配列は上のように入力する必要がありますが、コードは面倒です.
💡 この場合、spread演算子*を使用して配列をスキップできます.
println(max(*values))
配列はスプレッドシートを直接使用できますが、リストにスプレッドシートを直接適用することはできません.
リストが整列に変更された後、スプレッドシートが適用されます.
println(max(*listOf(1, 4, 18, 12).toIntArray()))

vararg演算子とspread演算子の組み合わせがコードを調整することがわかります.

📌 こうぞうぶんかい


構造化は、他の変数の値でオブジェクトを作成します.
逆に,構造分解は既存のオブジェクトから変数として値を抽出する.
コトリンの構造分解は,属性の名前ではなく属性の位置に基づいて行われる.

入力

fun getFullName() = Triple("John", "Quincy", "Adams")

val result = getFullName()
val first = result.first
val middle = result.second
val last = result.third
println("$first $middle $last")

💻 しゅつりょく

John Quincy Adams
関数の戻りタイプがTriple、Pair、または他のデータクラスの場合、構造分解によって変数に値を明確に割り当てることができます.
val (first, middle, last) = getFullName()
println("$first $middle $last")
4行のコードを1行のコードに変更する
この3つの交流可能な値first、medial、lastは、getFullName()関数で返されるtriple property順に値を割り当てます.
このコードは、Tripleクラスが構造変化のための特別な方法を持っているため可能である.
val (first,_,last)=getFullName()
println("$first $last")
不要な属性値がある場合は、参照スコア()を使用してその属性をスキップできます.

🔑 整理する


コトリンはユーザーにメソッドの作成を強制しません.
コトリンの基本パラメータ機能は関数を拡張しやすくし,関数の過負荷を低減した.
varargはセキュリティを提供し、非常に柔軟な複数のパラメータにまたがる能力を提供します.
spread演算子はvarargパラメータに配列を簡単に渡すことができる.
明示的なパラメータを使用すると、コード自体が記録されます.
構造分解はコードの干渉要因を低減し,コードを非常に簡潔にする
ソース:マルチファンクションエラープログラミング