「Kotlin コア プログラミング」ノート: 式指向プログラミング

式指向プログラミング

平たく言えば、式は値を返すことができるステートメントです

1 // 单纯的字面量表达式,值为1
-1 // 增加前缀操作符,值为-1
1+1 // 加法操作符,返回2
listOf(1,2,3) // 列表表达式 
"kotlin".length // 值为6 

これらは非常に明白な表現です。 Kotlin のより複雑な式の例を次に示します。

{
    
    x: Int -> x + 1} // Lambda 表达式,类型为 (Int) -> Int
fun(x: Int) {
    
     println(x) } // 匿名函数表达式,类型为 (Int) -> Unit
if (x > 1) x else 1 // if—else表达式,类型为 Int,假设 x 已赋值

式はステートメントより安全です

void ifStatement(Boolean flag) {
    
    
    String a = null;
    if (flag) {
    
    
        a = "dive into kotlin";
    }
    System.out.println(a.toUpperCase());
}

Java では、if は式ではなくステートメントであるため、変数 a をここで宣言する必要があります。このコードの潜在的な問題は次のとおりです。 a は、 if ステートメントの外側で宣言し、 条件を前提として null に初期化する必要があります。が常に である場合、プログラムは実行時にエラーを報告しません。そうでない場合は、(コンパイルが成功した場合でも) 実行時に null ポインター例外がスローされます。それが副作用です。 flagtrue

次の Kotlin バージョンでは、if を式として使用してもこの問題は発生しません:

fun ifExpression(flag: Boolean) {
    
    
    val a = if (flag) "dive into Kotlin" else ""
    println(a.toUpperCase())
}

if が式として使用される場合、 else 分岐も考慮する必要があります。式には型情報があり、最終的には式に型情報があるため、これは理解しやすいです。その A タイプは、 ifelse 複数のブランチ タイプと同じタイプまたは共通の親タイプです。式ベースのソリューションによって副作用が完全に排除され、プログラムがより安全になっていることがわかります。 Java 関数とは異なり、Kotlin のすべての関数呼び出しも式です

ユニットタイプ: 関数呼び出しを式にする

Java の関数がすべての式ではないのはなぜですか? 特殊なケースがあるためvoidvoid関数には戻り値の型がないため、数えることはできません 式を作成します。

では、なぜ Kotlin は Unit を導入するのでしょうか?大きな理由は、関数型プログラミングが組み合わせ、特に多くの高階関数に焦点を当てており、これらの関数はソース コードに実装するときにジェネリックスを使用して実装されるためです。ただしvoidジェネリックが関与する場合には問題が発生します。

複合式: 表現力の向上

ステートメントと比較すると、式は自己完結型になる傾向があり、コンテキストとの状態の共有や相互依存を避けるため、分離性が優れていると言えます。。分離とは副作用を排除することを意味し、式を使用してロジックをより安全に記述することができます。さらに、式はより表現力豊かになることがよくあります。

典型的な例は、式を組み合わせるのが簡単です。各式には値があり、それ自体の一部として別の式を構成することもできるため、複合式を作成できます。

val res: Int? = try {
    
    
    if (result.success) {
    
    
        jsonDecode(result.response)
    } else null
} catch (e: JsonDecodeException) {
    
    
    null
}

このプログラムは、HTTP 応答結果を取得し、json をデコードして、最後に res 変数に割り当てるプロセスを記述します。これは、Kotlin が複数の式を組み合わせる機能をどのように活用しているかを示しています。

  • try も Kotlin の式です。try/catch/finally 構文の戻り値の型は、try または catch 部分。finally影響はありません。
  • Kotlin では、if-else は従来の三項演算子を大幅に置き換えます。文法上の単語の数は増えますが、概念が減り、読みやすくなります。
  • if-else の戻り値は try 部分の戻り値であり、 res の最終値は try またはcatch部分的な決定。

Kotlin の「?:」

Kotlin は三項演算子を使用しませんが、非常に似た構文「?:」を持っています。ここでは疑問符とコロンを一緒に使用する必要があることに注意してください。これは Elvis 演算子、または null< と呼ばれます。 /span> 演算子を理解することができます: Elvis」を使用して null 許容型の変数を、空のケース。次の例を通して、?」を使用して型の null 可能性を示すことができるため、「 合体演算子。 Kotlin では、「?:

val maybelnt: Int? = null
maybelnt ?: 1 // 1

Enum クラスと when 式

列挙型はクラスです

Kotlin では、列挙は列挙クラスを通じて実装されます。

enum class Day {
    
     
    MON, TUE, WED, THU, FRI, SAT, SUN 
}

Java と比較すると、記述上のキーワードが 1 つだけ多いcalssですが、Java の列挙とは異なり、型であるため、構築パラメータを持つことができ、追加のプロパティとメソッドを定義できます。 。

enum class DayOfWeek(val day: Int) {
    
    
    MON(1),
    TUE(2), 
    WED(3), 
    THU(4), 
    FRI(5), 
    SAT(6), 
    SUN(7);
    // 如果以下有额外的方法或属性定义,则必须强制加上分号
    fun getDayNumber(): Int {
    
    
        return day
    }
}

if-else の代わりに when を使用する

fun schedule(sunny: Boolean, day: Day) = when (day) {
    
    
    Day.SAT -> basketball()
    Day.SUN -> fishing()
    Day.FRI -> appointment()
    else -> when {
    
    
        sunny -> library()
        else -> study()
    }
}

when式の具体的な構文は次のとおりです。

  • 1) 完全な when 式は switch ステートメントに似ており、 when キーワードで始まり、curly を使用します。括弧 複数の論理分岐が含まれており、それぞれが -> で接続されており、 switchbreak は必要ありません (これは本当に面倒なキーワードです)。すべての一致が完了するまで上から下に一致します。完了しない場合は、 else 分岐のロジックが実行されます。 9> ;switchdefault
  • 2) 各論理分岐には戻り値があり、最終的に when 式全体の戻り値の型は、すべての分岐で同じ戻り値の型、または共通の親の型になります。
  • 3) when キーワードのパラメータは、上記のコードの subwhen 式のように省略できます (ただし、この場合は a> ->左側のものはブール値を返す必要があります。そうでない場合、コンパイルでエラーが報告されます)
  • 4) 式は組み合わせることができるため、これは式の組み合わせの典型的な when 例です。 Java ではこのような長い式はほとんど見られませんが、Kotlin では非常に一般的です。

when式をより柔軟な方法で使用して、深くネストされた問題を解決することもできます。

fun schedule(sunny: Boolean, day: Day) = when {
    
    
    day == Day.SAT -> basketball()
    day == Day.SUN -> fishing()
    day == Day.FRI -> appointment()
    sunny -> library()
    else -> study()
}

ここでも、when() のパラメータが省略されている場合、各分岐の左側は Boolean 型を返す式である必要があります。

for ループと範囲式

for (i in 1..10) println(i) 

これは次の記述と同等です。

for (i: Int in 1..10) {
    
     
	println(i)
}

実際、イテレータを提供する構造は、次のような for-in ステートメントを使用して反復できます。

for (c in array) {
    
     
	println(c)
}

さらに、withIndex メソッドを呼び出して、キーと値のタプルを提供することもできます。< /span>

for ((index, value) in array.withlndex()) {
    
     
	println("the element at $index is $value") 
}

範囲式

Kotlin 公式 Web サイトでは、Range 式は rangeTo 関数を通じて実装され、「..」演算子によって構成されます。特定の型のオブジェクト。この型は、整数の基本型に加えて、 java.lang.Comparable インターフェイスを実装する必要があります。

たとえば、String クラスは Comparable インターフェイスを実装しているため、文字列値を比較できるため、次のような文字列 Interval を作成できます。として:

"abc".."xyz"

さらに、整数forをループする場合、Kotlin はstep 反復 ステップ サイズを定義する関数:

for (i in 1..10 step 2) {
    
    
	print(i)
} 
>>> 13579

逆の順序:

for (i in 10 downTo 1 step 2) {
    
     // 通过 downTo,而不是 10..1
    print(i) 
}
>>> 108642

さらに、半開間隔を実装するuntil関数もあります。

for (i in 1 until 10) {
    
     
	print(i) 
} 
>>> 123456789 // 并不包含 10

メンバーシップを確認するために使用します

Kotlin では、in を使用して、要素が範囲またはセットのメンバーであるかどうかを確認できます。

"a" in listOf("b", "c") 
>>> false

in の前に感嘆符を追加すると、逆の結果は次のようになります。

"a" !in listOf("b", "c") 
>>> true

等号と不等号に加えて、in を範囲式と組み合わせて、より多くの意味を表現することもできます。

"kot" in "abc".."xyz" 
>>> true

上記のコードは次と同等です。

"kot" >= "abc" && "kot" <= "xyz" 

中置式

infix 関数の表現形式は非常に単純で、次のように理解できます。

A 中缀方法 B

infix 関数を定義したい場合は、次の条件を満たしている必要があります。

  • infix 関数は、特定の型の拡張関数またはメンバー メソッドである必要があります。
  • この中置関数にはパラメーターを 1 つだけ指定できます。
  • 中置関数のパラメータにはデフォルト値を設定できません (ただし、Kotlin の関数パラメータはデフォルト値をサポートしています)。そうしないと、上記の形式の B が欠落し、中置式のセマンティクスに影響します。損害を与える;
  • パラメータの数を常に 1 に保つ必要があるため、このパラメータを可変個引数パラメータにすることはできません

Kotlin 標準ライブラリの中置式を使用して設計された to メソッドを見てみましょう。これはジェネリックを通じて実装されたメソッドであり、Pair

infix fun <A, B> A.to(that: B): Pair<A, B> 

toPair のキーと値のペアの構造データを返すため、よくそれを map と比較します。一緒に。例:

mapOf(
	1 to "one",
	2 to "two",
	3 to "three"
)

中置式をカスタマイズします。

class Person {
    
    
    infix fun called(name: String) {
    
    
        println("My name is $name.")
    }
}

fun main() {
    
    
    val p = Person()
    p called "Shaw" // 输出:My name is Shaw. 
} 

これは従来の方法と呼ぶこともできます。

p.called("Shaw")

おすすめ

転載: blog.csdn.net/lyabc123456/article/details/135010189