Kotlinのキーワードとコメント

1.キーワード:

Kotlinキーワードリスト

キーワードと演算子(公式)

https://blog.csdn.net/dota_wy/article/details/76060078(推奨)

の意味

コトリンで単独で使用されますか?空の手段

Kotlinコード記述形式:

var result = str?.length

Javaコード記述形式:

if(str == null)
    result = null;          // 这里result为一个引用类型
else
    result = str.length;    // 这里result为Int

一部の人々は、「?」を追加することと追加しないことの基本的な違いを疑っています。実行中のプログラムへの変数の代入にあり、「?」を持たない変数にnullを代入するとプログラムが異常になります。

?:意味

Kotlinの三項演算子(つまり、三項演算子)を表します

var str : String? = null
var result = str?.length ?: -1
//等价于
var result : Int = if(str != null) str.length else -1

:(コロン)

タイプとスーパータイプの間のコロンの前にはスペースを入れてください。インスタンスとタイプの間のコロンの前にはスペースを入れないでください:

interface Foo<out T : Any> : Bar {
    fun foo(a: Int): T
}

Kotlinにはパッケージレベルの関数を含めることができるため、メイン関数をラップするクラスを宣言する必要はありません。

fun main(args: Array<String>){
    ...
}

::(二重コロン)

ダブルコロン演算子は、メソッドがパラメータとして使用され、別のメソッドに渡されて使用されることを示します。一般的には、メソッドを指します。

https://blog.csdn.net/lv_fq/article/details/72869124

/**
 * @param p1 参数1
 * @param p2 参数2
 * @param method 方法名称
 */
fun lock(p1: String, p2: String, method: (str1: String, str2: String) -> String): String {
    return method(p1, p2)
}

::クラス

クラスのインスタンスを取得する方法

Javaの中で:

public class Hello{
    ...
}

...

Class<?> clazz = Hello.class;

Hello hello = new Hello();
Class<?> clazz2 = hello.getClass();

Kotlinの中で:

class Hello

val clazz = Hello::class.java

val hello = Hello()
val clazz2 = hello.javaClass

同じ効果を持つKotlinコードは奇妙に見えます。実際、Hello ::クラスはKotlinのタイプであるKotlinのKClass
を取得します。Javaクラスインスタンスを取得するには、Hello :: class.javaが必要です。 。

!!(二重感嘆符)

「ここには未処理の潜在的なKotlinNullPointerExceptionがあります」を意味します

Kotlinでは、空にすることはできません。

var result : Int = str!!.length

https://zhuanlan.zhihu.com/p/27285806

概要 :

抽象クラスクラスまたは一部のメンバーは、抽象クラスとして宣言できます。抽象メソッドのクラスには実装メソッドがありません。
抽象クラスまたは関数にオープンアノテーションを追加する必要はありません。デフォルトで付属しています。

open class Base {
    open fun f() {}
}

abstract class Derived : Base() {
    override abstract fun f()
}

どれか:

Javaのオブジェクトに相当します。

沿って

クラスの委任、属性の委任

コンパニオンオブジェクト:

静的に似ています。

kotlinでは、javaやC#とは異なり、静的メソッドはありません。ほとんどの場合、パッケージレベル機能。

インスタンスクラスなしで呼び出すことができるメソッドを記述したいが、クラスの内部(ファクトリメソッドなど)にアクセスする必要がある場合は、クラスのメンバーとしてそれを書き込むことができます(オブジェクトのメンバーとして書き込むことができます)そのクラス内での宣言)より効率的な方法は、クラスでコンパニオンオブジェクトを宣言して、java / c#のような静的メソッド呼び出しとして使用できるようにすることです。クラス名を認識する必要があるだけです。あまりにも。

例:グローバルアプリケーションインスタンスを取得する

companion object {
        lateinit var instance: App
    }

const:

const修飾子を使用してコンパイル時の定数としてマーク

コンストラクタは、コンストラクタを識別するために使用されます

class Customer(name: String){
    init {
        logger,info("Customer initialized with value ${name}")
    }
}

二次コンストラクタ

class Person { 
    constructor(parent: Person) {
        parent.children.add(this) 
    }
}    

https://blog.csdn.net/dota_wy/article/details/76060078

3.1注:kotlinのクラス定義もコンストラクターです。現時点では操作できないため、kotlinはクラスの初期化を処理するために新しいキーワードinitを追加しました。initモジュールのコンテンツはコンストラクターを直接使用できますパラメータ。

class Person(name:String,age:int){
    init{
        //do some thiing
    }
}

3.2。finalは継承不可としてJavaに追加され、Kotlinで定義されたクラスは修飾子finalでデフォルト設定されるため、クラスを継承する場合は、openまたはabstractを先頭に追加します。つまり:

open class Person(name : String, age : int) {
    init{  
        // do some thing
    } 
}

3.3 initに操作がない場合は省略可能

class Person(name : String, age : int)

3.4。パラメータがない場合は、次のように書くこともできます

class Person

3.5。ただし、構築パラメーターのパラメーターと型が変更される場合、複数のコンストラクターが必要になることがあります。異なるビューでデータを処理するために複数のコンストラクターセットが必要な場合は、コンストラクターを使用してパラメーターを追加し、これを使用してメインコンストラクターを追加します。パラメータ。
二次コンストラクタ

class Person(name:String){
    var a = 1
    init{
        log("This is --> primary constructor,a = $a,name = $name")
    }
    constructor(name:String,age:Int): this(name){
        log("This is --> secondry constructor,a = ${++a}, age = $age")
    }
}

データクラス:

Kotlinのデータクラス

データクラスは、一部のデータフィールドのみを含むクラスです。

コンパイラは私たちのために静かに以下を生成しました

  • equals()/ hashCode()
  • toString()メソッド
  • componentN()メソッド「解体の達成」
  • copy()メソッド

単純なデータクラスを宣言する方法 いくつかの要件があります。

  • メインコンストラクターには少なくとも1つのパラメーターが必要です(つまり、データフィールドが必要です。hashCode、equals、toStringはメインコンストラクターに従って生成されます)

  • メインコンストラクターのすべてのパラメーターは、valまたはvarとしてマークする必要があります(Javaで手動でset getを生成する目的を達成する、データフィールドのアクセス許可を示すのと同等)

  • データクラスに次の修飾子を含めることはできません:抽象、内部、オープン、シール

  • データクラスはインターフェース(Kotlin 1.1の以前のルール)のみを実装でき、他のクラスも継承できるようになりました

    データクラスUser(var id:Int、var name:String)

インデックス:

列をなして:

役割:インライン関数を変更します。

呼び出されたラムダ式または関数に多数の実行コードが含まれている
場合は、インライン関数を使用しないでください。呼び出されたラムダ式または関数に非常に単純な実行コードのみが含まれている場合は、インライン関数を使用してください。

インナー:

ネストされたクラス:

クラスBにクラスAのメンバーにアクセスさせたい場合は、内部タグを追加できます。

class A {
    val a: String = "a"
    inner class B {
        val b: String = a
    }
}

訪問:

val a = A().B().b//a输出为“a”

内部:

Kotlinプログラミングには4つの修飾子があります。プライベート、保護、内部、パブリック、デフォルトの修飾子はパブリックです。

  • 内部ステートメント。同じモジュールのどこからでも参照できます。
fun main(args: Array<String>) {
        Test().test()
    }
    open  class BaseTest{
        private val a="该属性不能被子类访问"
        protected var b="该属性能被子类访问"
        internal var c="同一模块下被访问"
        var d="到处都可以被访问"
    }
    class Test:BaseTest(){
        fun  test(){
            println(b)
            println(c)
            println(d)
        }
    }

です:

Javaのinstanceofと同等

lateinit var late初期化プロパティ:

通常、null以外の型として定義されているプロパティは、コンストラクターで初期化する必要がありますが、これはそれほど便利ではない場合があります。

たとえば、単体テストでは、プロパティは依存関係注入またはセットアップメソッドを使用して初期化する必要があります。この条件下では、コンストラクターに空でない初期化ステートメントを指定できませんが、このプロパティにアクセスする必要があります、非nullチェックを回避します。

この状況を処理するには、lateinit修飾子をこのプロパティに追加します

注:lateinitによって変更される変数/属性 できない 元のデータ型です。

public class MyTest {
    lateinit var subject: TestSubject

    @SetUp fun setup() {
        subject = TestSubject()
    }

    @Test fun test() {
        subject.method() 
    }
}

この修飾子は、コンストラクターではなく、クラスのvar型の変数属性定義でのみ使用できます。また、属性にはカスタムゲッターおよびセッターアクセサーを含めることはできません。この属性の型は空でなくてはなりません。基本型にすることはできません。
初期化前に遅延初期化プロパティにアクセスすると、アクセス時に値が初期化されていないことを示す特定の例外が発生します。

初期化の前にlateinitプロパティにアクセスすると、特定の例外がスローされ、プロパティにアクセスしたことと、プロパティが初期化されなかったことが明確に識別されます。

遅延(遅延読み込み)

val p: String by lazy {
    // 生成string的值
}

Kotlinの遅延初期化:lateinit varおよび遅延

  • lateinitはvarにのみ使用され、lazyはvalにのみ使用されます
  • lateinit varは、プロパティの初期化されていないチェックをコンパイル時に無視させるだけです。いつどこで初期化するかは、開発者が決定する必要があります。
  • lazyは実際に宣言を行い、遅延初期化の動作も指定します。これは、属性が初めて使用されるときに自動的に初期化できます。

オブジェクト(シングルトンパターンの作成に使用):

object Resource {
    val name = "Name"
}

openステートメントは継承できます。

openアノテーションはJavaのfinalの逆です。他のクラスがこのクラスを継承できるようにします。

デフォルトでは、Kotlinのすべてのクラスはfinalであり、継承できることを示すために使用されます。

したがって、親クラスはopenを使用してクラスを宣言します。それ以外の場合、デフォルトはfinalであり、継承できません。

変更されたクラス:説明を継承できる

open class Base(p: Int)

class Derived(p: Int) : Base(p)

変更されたメンバー:Kotlinで明確なことを行うように要求します。Javaとは異なり、kotlinは上書き可能なメンバーに明示的に注釈を付け、それらを再書き込みする必要があります

open class Base {
    open fun v() {}
    fun nv() {}
}

class Derived() : Base() {
    override fun v() {}
}

オーバーライド:

具現化:

封印:

封印されたクラスは、厳密なクラス構造を表すために使用され、値は限定されたセット内の特定のタイプにのみなり、他のタイプにはなりません。これは、列挙型クラスの拡張と同等です。列挙値セットのタイプは厳密に制限されますが、各列挙型定数にはインスタンスが1つしかなく、シールされたクラスのサブクラスは、異なる状態を含む複数のインスタンスを持つことができます。
封印されたクラスを宣言するには、クラスの前に封印された修飾子を追加する必要があります。封印されたクラスはサブクラスを持つことができますが、すべて封印されたクラス宣言内にネストする必要があります。

sealed class Expr {
    class Const(val number: Double) : Expr() 
    class Sum(val e1: Expr, val e2: Expr) : Expr() 
    object NotANumber : Expr()
}

封印されたクラスのサブクラスの拡張はどこでも可能であり、封印されたクラス宣言内で行う必要がないことに注意してください。
シールドクラスを使用する主な利点は、式を使用することです。宣言がすべての状況をカバーできることを確認できます。他の状況を使用する必要はありません。

fun eval(expr: Expr): Double = when(expr) { 
    is Const -> expr.number
    is Sum -> eval(expr.e1) + eval(expr.e2) 
    NotANumber -> Double.NaN
    // the `else` clause is not required because we've covered all the cases
}

tailrec(テール再帰):

機能:スリムテール再帰機能。通常の再帰と比較して、コンパイラーは末尾再帰を変更し、それを高速で効率的なループベースのバージョンに最適化します。これにより、メモリー消費が削減されます。

tailrec fun test3(n: Int, total: Int = 1): Int =
    if (n == 1)
        total
    else
        test3(n - 1, total * n)

ユニットタイプ:

関数がUnit型を返す場合、戻り値の型は省略してください。

varとval:

varは変数変数であり、再配布によって別の値に変更できる変数です。変数を宣言するこの方法は、Javaで変数を宣言する方法と同じです。
valは読み取り専用の変数で、変数を宣言するこの方法は、Javaのfinal変数と同等です。valは後で変更できないため、作成時に初期化する必要があります。

typealias:

タイプエイリアスを定義します。

可変引数:

機能:可変パラメーター。関数は最大で1つの変数パラメーターしか持つことができません。

fun asList<T>(vararg ts: T): List<T> {
    val result = ArrayList<T>()
    for (t in ts)
        result.add(t)
    return result
}

マーキング後、可変長パラメーターを関数に渡すことができます。

val list = asList(1, 2, 3)

javaのswitch()ステートメントの同等物を判断するために使用される場合

分岐時:

  • ケースキーワードは不要になりました
  • ケース値が矢印(->)を使用するように変更された後のコロン
  • デフォルトをより意味のある明確なものに変更
  • ブランチが複数の値と一致できる場合
  • ブランチが任意の式になる場合
  • ブランチが条件式のタイプに要件を持たない場合
    when(color) {
            "Red" -> 0
            "Green" -> 1
            "Blue" -> {
                println("2")
                println("3")
            }}
            else -> throw IllegalArgumentException("Invalid color param value")
        }

式として分岐する場合:

fun test(){
    var score='B'
    
    val str= when(score){
        "A"->"优秀"
        "B"->"良好"
        "C"->"及格"
        else->{
            println("继续努力啊")
            "不及格"
        }
    }
}

処理範囲(in ...)、処理タイプ(is Int、is Double ...):

fun test1(){
    var score='B'
    
    val str= when(score){
        in 80..100->"优秀"
        "B"->"良好"
        "C"->"及格"
        is String->"属于字符串类型"
        else->{
            println("继续努力啊")
            "不及格"
        }
    }
}

2.注意事項:

@JvmField

https://www.kotlincn.net/docs/reference/java-to-kotlin-interop.html#%E9%9D%99%E6%80%81%E5%AD%97%E6%AE%B5

静的フィールド:
名前付きオブジェクトまたはコンパニオンオブジェクトで宣言されたKotlinプロパティは、その名前付きオブジェクトまたはコンパニオンオブジェクトを含むクラスに静的な舞台裏フィールドを持ちます。

通常、これらのフィールドはプライベートですが、次のいずれかの方法で公開できます。

  • @JvmFieldアノテーション;(パブリック静的最終フィールド)
  • lateinit修飾子;(public static 非最終 フィールド)
  • const修飾子。(静電界)

@JVMStatic

https://www.kotlincn.net/docs/reference/java-to-kotlin-interop.html#%E9%9D%99%E6%80%81%E6%96%B9%E6%B3%95

静的メソッド:
「コンパニオンオブジェクト」のパブリック関数は、静的メソッドとして公開されるように@JvmStaticで注釈を付ける必要があります。

@JvmStaticアノテーションを使用すると、コンパイラーは、対応するオブジェクトのクラスの静的メソッドとオブジェクト自体のインスタンスメソッドの両方を生成します。
このアノテーションがなければ、これらの関数は静的なコンパニオンフィールドのインスタンスメソッドとしてのみ使用できます。

3.スコープ機能

スコープ機能(公式)

Kotlinの関数let、apply、with、runの違い

Kotlinのlet、apply、run、withなどの機能の違い2

Kotlin標準ライブラリには、オブジェクトのコンテキストでコードブロックを実行することを唯一の目的とするいくつかの関数が含まれています。このような関数がオブジェクトで呼び出され、ラムダ式が提供されると、一時的なスコープが形成されます。このスコープでは、名前なしでオブジェクトにアクセスできます。これらの関数はスコープ関数と呼ばれます。let、run、with、apply、および5つのタイプがあります。

各スコープ関数には2つの主な違いがあります。

  • コンテキストオブジェクトを参照する方法
  • 戻り値
関数名 定義 パラメータ 戻り値 拡張
させる fun T.let(f:(T)-> R):R = f(this) それ クロージャーリターン はい
適用する fun T.apply(f:T.()-> Unit):T {f(); これを返す} いいえ、これを使用できます この はい
fun with(receiver:T、f:T.()-> R):R = receiver.f() いいえ、これを使用できます クロージャーリターン いいえ、呼び出し方法は異なります
走る fun T.run(f:T.()-> R):R = f() いいえ、これを使用できます クロージャーリターン はい

させる

デフォルトでは、このオブジェクトはクロージャーのitパラメーターとして使用され、戻り値は関数内にあります最終行、または返品を指定

適用:

適用関数はこれであり、関数のスコープ内でオブジェクトの適用関数を呼び出し、オブジェクトの任意のメソッドを呼び出すことができます。オブジェクトを返す

apply関数はrun関数と非常によく似ています。唯一の違いは、それらが返す値が異なることです。run関数は、コードの最後の行の値をクロージャの形式で返し、apply関数の戻りはオブジェクト自体です。

実行:

run関数は、run関数が使用されることを除いて、apply関数と非常に似ています。最終行Return、applyは現在のオブジェクトを返します。

run関数は、letとwith関数の組み合わせです。正確には、let関数は関数本体のオブジェクトの代わりにitパラメーターを使用する必要があります。run関数では、with関数のように省略でき、インスタンスのパブリックプロパティとメソッドに直接アクセスできます。一方、with関数で渡される空中判定の問題を補い、run関数では、let関数のように空中判定処理を行うことができます。

と:

with関数は別の関数であり、Kotlinの拡張ではないため、呼び出しメソッドは少し異なり、戻り値は最終行次に、オブジェクトのメソッドを直接呼び出すことができます。これは、letとapplyの組み合わせのように感じます。

また

コンテキストオブジェクトは、ラムダ式のパラメーター(it)としてアクセスされます。戻り値は、コンテキスト自体の反対です。

4.クラスを定義する

4.1、属性修飾子

  • アノテーション//アノテーションクラス
  • abstract //抽象クラス
  • final //クラスは継承可能ではなく、デフォルトのプロパティ
  • enum //列挙クラス
  • open //クラスは継承できます。クラスはデフォルトでfinalです

4.2、アクセス権修飾子

  • private //同じファイルでのみ表示
  • protected //同じファイルまたはサブクラスで可視
  • public //すべての通話場所が表示されます
  • 内部//同じモジュールで可視
オリジナルの記事を45件公開 24のように 50,000以上の訪問

おすすめ

転載: blog.csdn.net/zhijiandedaima/article/details/90403425