Kotlin
Kotlinは、Java仮想マシンで実行される静的に型指定されたプログラミング言語です。KotlinはJavaバイトコードまたはJavaScriptにコンパイルできるため、JVMのないデバイスでの実行に便利です。
Kotlinプログラムファイルは.ktにあります
Kotlinを選ぶ理由
- シンプルさ:ボイラープレートコードの量を大幅に削減します。
- セキュリティ:nullポインタ例外などのエラーのクラス全体を回避します。
- 相互運用性:JVM、Android、およびブラウザーの既存のライブラリーを最大限に活用します。
- ツールフレンドリー:任意のJavaIDEまたはコマンドラインを使用して構築できます。
Kotlinの基本構文
デフォルトでインポートデフォルトで
各Kotlinファイルにインポートされる複数のパッケージがあります。
kotlin.*
kotlin.annotation.*
kotlin.collections.*
kotlin.comparisons.*
kotlin.io.*
kotlin.ranges.*
kotlin.sequences.*
kotlin.text.*
関数定義
関数定義はキーワードfunを使用し、パラメーター形式は次のとおりです。パラメーター:タイプ
fun sum(a: Int, b: Int): Int { // Int 参数,返回值 Int
return a + b
}
関数の本体としての式、戻り値の型は自動的に推測されます
fun sum(a: Int, b: Int) = a + b
public fun sum(a: Int, b: Int): Int = a + b // public 方法则必须明确写出返回类型
戻り値のない関数(Javaのvoidと同様):
fun printSum(a: Int, b: Int): Unit {
print(a + b)
}
// Unitタイプを返す場合は、省略できます(パブリックメソッドについても同じです)。
public fun printSum(a: Int, b: Int) {
print(a + b)
}
可変長パラメーター関数関数の可変長パラメーターは
、varargキーワードで識別できます。
fun vars(vararg v:Int){
for(vt in v){
print(vt)
}
}
// 测试
fun main(args: Array<String>) {
vars(1,2,3,4,5) // 输出12345
}
ラムダ(無名関数)
ラムダ式の使用例:
// 测试
fun main(args: Array<String>) {
val sumLambda: (Int, Int) -> Int = {x,y -> x+y}
println(sumLambda(1,2)) // 输出 3
}
定数と変数の
定義変数変数の定義:varキーワード
var <識別子>:<タイプ> = <初期値>
不変変数の定義:valキーワード、一度だけ割り当てることができる変数(Javaで最終的に変更された変数と同様)
val <識別子>:<タイプ> = <初期化値>
定数と変数には初期化値を含めることはできませんが、参照する前に初期化する必要があります
コンパイラは自動型判定をサポートしています。つまり、型は宣言で指定されていない可能性があり、コンパイラはそれを判定します。
コメント
Kotlinは1行コメントと複数行コメントをサポートしてい
ます。Javaとは異なり、Kotlinのブロックコメントではネストが可能です。
文字列テンプレート
$は、変数名または変数値を
表します$ varNameは、変数値を表します
$ {varName.fun()}は、変数メソッドの戻り値を表します。
var a = 1
//テンプレート内の単純な名前:
val s1 = "a is $a"
a = 2
// 模板中的任意表达式:
val s2 = "${s1.replace("is", "was")}, but now is $a"
Kotlinのnull安全設計のnullチェックメカニズム。null可能であると宣言されたパラメータの場合、それらを使用するときにnull判定処理を実行する必要があります。2つの処理方法があります。フィールドの後に追加します!! Javaのようなnull例外をスローし、次々に追加します。フィールド?処理できず、戻り値がnullまたは協調できませんか?:短い判定処理
//类型后面加?表示可为空
var age: String? = "23"
//抛出空指针异常
val ages = age!!.toInt()
//不做处理返回 null
val ages1 = age?.toInt()
//age为空返回-1
val ages2 = age?.toInt() ?: -1
参照がnull値である可能性がある場合、対応する型宣言はnull許容型検出および自動型変換として明確にマークする必要があります。is
演算子を使用して、式が特定の型のインスタンスであるかどうかを検出できます(inのinstanceofと同様)。 Javaキーワード)
fun getStringLength(obj: Any): Int? {
if (obj is String) { //或者 !is
// 做过类型判断以后,obj会被系统自动转换为String类型
return obj.length
}
// 这里的obj仍然是Any类型的引用
return null
}
Range
範囲式は、演算子形式のrangeTo関数によって形成されます。inおよび!inで補足されます。Range
は、同等の型に対して定義されますが、整数プリミティブ型の場合、実装が最適化さ
れます。//stepを使用してsteplongを指定します。
for (i in 1..4 step 2) print(i) // 输出“13”
for (i in 4 downTo 1 step 2) print(i) // 输出“42”
// 使用 until 函数排除结束元素
for (i in 1 until 10) { // i in [1, 10) 排除了 10
println(i)
}
================================================== =============================
Kotlinの基本的なデータ型
Kotlinの基本的な数値型には、Byte、Short、Int、Long、Float、Doubleなどがあります。
Javaとの違いは、文字は数値型ではなく、独立したデータ型であるということです。
タイプビット幅
ダブル64
フロート32
ロング64
整数32
ショート16
バイト8
リテラル定数
以下は、すべてのタイプのリテラル定数です。10進数
:123
長整数は大文字で終わりますL:123L
16進数は0xで始まります:0x0F
2ベースは0bで始まります:0b00001011
注:8進数はサポートしていません
Kotlinは、従来の記号で表される浮動小数点値もサポートしています:
Doublesデフォルトの書き込み:123.5、123.5e10浮動小数点
はfまたはFサフィックスを使用します:123.5f
アンダースコアを使用して、数値定数を読みやすくすることができます
val oneMillion = 1_000_000
2つの数値の比較
Kotlinには基本的なデータ型はなく、カプセル化された数値型のみがあります。変数を定義するたびに、Kotlinは実際にオブジェクトをカプセル化するため、nullポインターがないことを保証できます。
数値の種類も同じであるため、2つの数値を比較する場合、データのサイズを比較する場合と、2つのオブジェクトが同じであるかどうかを比較する場合には違いがあります。
Kotlinでは、3つの等号===はオブジェクトアドレスを比較することを意味し、2つの==は2つの値を比較することを意味します。
型変換
表現が異なるため、小さい型は大きい型のサブタイプではなく、小さい型を暗黙的に大きい型に変換することはできません。つまり、明示的な変換なしにByte値をInt変数に割り当てることはできません。
各データ型には次のメソッドがあり、他の型に変換できます。
toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
場合によっては、コンテキストに応じて正しいデータ型を推測でき、それに応じて数学演算子がオーバーロードされるという条件で、自動型変換を使用することもできます。
val l = 1L + 3 // Long + Int => Long
ビット演算子
Int型とLong型には、使用できる一連のビット演算子があります。
shl(bits) – 左移位 (Java’s <<)
shr(bits) – 右移位 (Java’s >>)
ushr(bits) – 无符号右移位 (Java’s >>>)
and(bits) – 与
or(bits) – 或
xor(bits) – 异或
inv() – 反向
文字
はJavaとは異なります。Kotlinの文字を数字で直接操作することはできません。文字は一重引用符で囲む必要があります。たとえば、通常の文字「0」、「a」。
文字リテラルは一重引用符で囲まれています:「1」。特殊文字は円記号でエスケープできます。次のエスケープシーケンスをサポートします:\ t、\ b、\ n、\ r、\ '、\ "、\\、および\ $。他の文字をエンコードするには、Unicodeエスケープシーケンス構文を使用します。' \ uFF00 '
は明示的に文字を変換します。整数
fun decimalDigitValue(c: Char): Int {
if (c !in '0'..'9')
throw IllegalArgumentException("Out of range")
return c.toInt() - '0'.toInt() // 显式转换为数字
}
ブールブール
はブール型で表され、trueとfalseの2つの値があります。
ヌル許容参照ブール値は、必要に応じてボックス化されます。
組み込みのブール演算は次のとおりです。
|| – 短路逻辑或
&& – 短路逻辑与
! - 逻辑非
配列
配列配列はクラスによって実装され、サイズと属性のgetメソッドとsetメソッドがあり、[]を使用すると、getメソッドとsetメソッドがオーバーロードされるため、配列に対応する位置または値を設定することで、取得したインデックスを簡単に作成できます。配列を作成する方法は2つあります。1つは関数arrayOf()を使用する方法で、もう1つはファクトリ関数を使用する方法です。
fun main(args: Array<String>) {
//[1,2,3]
val a = arrayOf(1, 2, 3)
//[0,2,4]
val b = Array(3, { i -> (i * 2) })
//读取数组内容
println(a[0]) // 输出结果:1
println(b[1]) // 输出结果:2
}
注:Javaとは異なり、Kotlinの配列は不変です。
クラスArrayに加えて、ByteArray、ShortArray、IntArrayもあります。これらは、さまざまなタイプの配列を表すために使用され、ボクシング操作の必要性を排除するため、より効率的であり、その使用法はArrayと同じです。
val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
文字
列Javaと同様に、文字列は不変です。角括弧[]構文は、文字列内の文字を取得するのに非常に便利です。また、forループを通過することもできます。
for (c in str) {
println(c)
}
Kotlinは、3つの引用符 "" "を含む文字列と複数行の文字列をサポートします
文字列はtrimMargin()メソッドを使用して余分な空白を削除できます。
デフォルト|は境界プレフィックスとして使用されますが、他の文字を選択して、trimMargin( ">")などのパラメータとして渡すことができます。
文字列テンプレート
文字列には、テンプレート式、つまり、評価されて結果が文字列にマージされるいくつかの小さなコードを含めることができます。テンプレート式はドル記号($)で始まり、単純な名前で構成
されます。または中括弧で囲まれた式:
fun main(args: Array<String>) {
val s = "runoob"
val str = "$s.length is ${s.length}" // 求值结果为 "runoob.length is 6"
println(str)
}
ネイティブ文字列とエスケープ文字列はどちらも、内部でテンプレートをサポートしています。リテラルの$文字をネイティブ文字列で表す必要がある場合(バックスラッシュのエスケープはサポートされていません)、次の構文を使用できます。
fun main(args: Array<String>) {
val price = """
${'$'}9.99
"""
println(price) // 求值结果为 $9.99
}
================================================== =============================式の場合のKotlin条件付き制御
// 传统用法
var max = a
if (a < b) max = b
// 使用 else
var max: Int
if (a > b) {
max = a
} else {
max = b
}
// 作为表达式
val max = if (a > b) a else b
IF式の結果を変数に割り当てることもできます
val max = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
これは、Javaのような三項演算子が必要ないことも示しています。これは、Javaを使用して簡単に実装できるためです。
val c = if (condition) a else b
間隔の
使用in演算子を使用して、数値が指定された間隔内にあり、間隔の形式がx..yであるかどうかを検出します。
fun main(args: Array<String>) {
val x = 5
val y = 9
if (x in 1..8) {
println("x 在区间内")
}
}
when式は
、ブランチが条件を満たすまで、そのパラメーターとすべてのブランチ条件を順番に比較します。
式またはステートメントとして使用できる場合。式として使用する場合、修飾されたブランチの値は式全体の値になります。ステートメントとして使用する場合、個々のブランチの値は無視されます。
whenは、他の言語のスイッチ演算子に似ています。その最も単純な形式は次のとおりです
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // 注意这个块
print("x 不是 1 ,也不是 2")
}
}
の場合、elseはスイッチのデフォルトと同じです。他のブランチが条件を満たさない場合、elseブランチが評価されます。
多くのブランチを同じ方法で処理する必要がある場合は、複数のブランチ条件をコンマで区切ってまとめることができます。
when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
値が間隔またはセット内にあるかどうか(!in)を検出することもできます
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
別の可能性は、値が特定のタイプの値であるかどうか(!is)を検出することです。注:スマート変換のおかげで、追加のテストなしでこのタイプのメソッドとプロパティにアクセスできます。
fun hasPrefix(x: Any) = when(x) {
is String -> x.startsWith("prefix")
else -> false
}
whenは、if-elseifチェーンの代わりにも使用できます。パラメータが指定されていない場合、すべての分岐条件は単純なブール式であり、分岐条件がtrueの場合、分岐が実行されます。
when {
x.isOdd() -> print("x is odd")
x.isEven() -> print("x is even")
else -> print("x is funny")
}
================================================== =============================
Kotlinループ制御
forループforループ
forループは、イテレーター(イテレーター)を提供する任意のオブジェクトをトラバースできます。構文は次のとおりです。
for (item in collection) print(item)
循环体可以是一个代码块
for (item: Int in ints) {
// ……
}
上記のように、forはイテレータを提供する任意のオブジェクトをループできます。
配列またはリストをインデックスで走査したい場合は、これを行うことができます
for (i in array.indices) {
print(array[i])
}
この「間隔でのトラバーサル」は、追加のオブジェクトを作成せずに、最適化された実装にコンパイルされることに注意してください。
または、ライブラリ関数withIndexを使用できます。
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
whileとdo ... whileループ
whileは最も基本的なループであり、その構造は次のとおりです。
while( 布尔表达式 ) {
//循环内容
}
do ... while loop forステートメントでは、条件が満たされない場合、ループに入ることができません。ただし、条件が満たされていない場合でも、少なくとも1回は実行する必要がある場合があります。
do ... whileループはwhileループに似ていますが、違いはdo ... whileループが少なくとも1回実行されることです。
do {
//代码语句
}while(布尔表达式);
戻ってジャンプ
Kotlinには、3つの構造化されたジャンプ式があります。
- 戻ります。デフォルトでは、それを最も直接囲む関数または無名関数から戻ります。
- ブレーク。ループを最も直接囲むループを終了します。
- 継続する。それを最も直接囲む次のサイクルに進みます
Kotlinは、ループ内の従来のブレークおよびコンティニュー演算子をサポートしています
fun main(args: Array<String>) {
for (i in 1..10) {
if (i==3) continue // i 为 3 时跳过当前循环,继续下一次循环
println(i)
if (i>5) break // i 为 6 时 跳出循环
}
}
ラベルの解除と続行
Kotlinの式には、ラベルを付けることができます。ラベルの形式は、識別子の後に@記号が続きます。たとえば、abc @とfooBar @はすべて有効なラベルです。式にラベルを付けるには、その前にラベルを追加する必要があります
loop@ for (i in 1..100) {
// ……
}
これで、ブレークを制限したり、ラベルを続行したりできます
loop@ for (i in 1..100) {
for (j in 1..100) {
if (……) break@loop
}
}
ラベル限定ブレークは、ラベルで指定されたループの直後の実行ポイントにジャンプします。続行は、ラベルで指定されたループの次の反復を続行します
ラベルで返される
Kotlinには、関数リテラル、ローカル関数、およびオブジェクト式が含まれています。そのため、Kotlin関数をネストできます。label-restricted returnを使用すると、外部関数から戻ることができます。最も重要な使用法の1つは、ラムダ式から戻ることです。これを書いたときのことを思い出してください
fun foo() {
ints.forEach {
if (it == 0) return
print(it)
}
}
この戻り式は、それを最も直接囲む関数、つまりfooから返されます。(この非ローカルリターンはインライン関数に渡されるラムダ式のみをサポートすることに注意してください。)ラムダ式から戻る必要がある場合は、ラベルを付けてリターンを制限する必要があります。
fun foo() {
ints.forEach lit@ {
if (it == 0) return@lit
print(it)
}
}
これで、ラムダ式からのみ返されます。通常、暗黙のタグを使用する方が便利です。ラベルは、ラムダを受け入れる関数と同じ名前です。
fun foo() {
ints.forEach {
if (it == 0) return@forEach
print(it)
}
}
または、ラムダ式の代わりに無名関数を使用することもできます。匿名関数内のreturnステートメントは、匿名関数自体から戻ります
fun foo() {
ints.forEach(fun(value: Int) {
if (value == 0) return
print(value)
})
}
戻り値を返す場合、パーサーはラベル制限付きの戻り値を優先的に選択します。つまり、
return @ a 1
は、「ラベルラベル付きの式(@a 1)を返す」ではなく、「ラベル@aから1を返す」ことを意味します。