0%

Kotlin学习2

依赖

core-ktx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
+--- androidx.core:core-ktx:1.7.0
| +--- org.jetbrains.kotlin:kotlin-stdlib:1.5.31
| | +--- org.jetbrains:annotations:13.0
| | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31
| +--- androidx.annotation:annotation:1.1.0 -> 1.2.0
| \--- androidx.core:core:1.7.0
| +--- androidx.annotation:annotation:1.2.0
| +--- androidx.annotation:annotation-experimental:1.1.0
| +--- androidx.lifecycle:lifecycle-runtime:2.3.1
| | +--- androidx.lifecycle:lifecycle-common:2.3.1
| | | \--- androidx.annotation:annotation:1.1.0 -> 1.2.0
| | +--- androidx.arch.core:core-common:2.1.0
| | | \--- androidx.annotation:annotation:1.1.0 -> 1.2.0
| | \--- androidx.annotation:annotation:1.1.0 -> 1.2.0
| \--- androidx.versionedparcelable:versionedparcelable:1.1.1
| +--- androidx.annotation:annotation:1.1.0 -> 1.2.0
| \--- androidx.collection:collection:1.0.0
| \--- androidx.annotation:annotation:1.0.0 -> 1.2.0

kotlin-stdlib

1
2
3
4
5
6
+--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20
| +--- org.jetbrains.kotlin:kotlin-stdlib:1.7.20
| | +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.7.20
| | \--- org.jetbrains:annotations:13.0
| \--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.20
| \--- org.jetbrains.kotlin:kotlin-stdlib:1.7.20 (*)

从上述看kotlin-stdlib是关键的kotlin库

基础

解构

1
2
3
4
5
6
7
8
9
10
11
12
fun main(args: Array<String>) {
val person = Person("songpengfei", 31)
val (name,age) = person
println(name)
println(age)
}

class Person(val name: String, val age: Int)

operator fun Person.component1() = name

operator fun Person.component2() = age

密封类

  • 每个枚举常量只存在一个实例,而密封类的一个子类可以有可包含状态的多个实例。

  • 有限几种类型。使用when时,不需要有else

    内联类

    1
    2
    3
    4
    5
    6
    7
    8
    inline class Name(val s: String) {
    val length: Int
    get() = s.length

    fun greet() {
    println("Hello, $s")
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    public final class Name {


    @Lkotlin/jvm/JvmInline;()

    @Lkotlin/Metadata;(mv={1, 7, 1}, k=1, xi=48, d1={"\u0000*\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\u000e\n\u0002\u0008\u0003\n\u0002\u0010\u0008\n\u0002\u0008\u0005\n\u0002\u0010\u000b\n\u0002\u0008\u0004\n\u0002\u0010\u0002\n\u0002\u0008\u0007\u0008\u0087@\u0018\u00002\u00020\u0001B\u0012\u0012\u0006\u0010\u0002\u001a\u00020\u0003\u00f8\u0001\u0000\u00a2\u0006\u0004\u0008\u0004\u0010\u0005J\u001a\u0010\u000c\u001a\u00020\r2\u0008\u0010\u000e\u001a\u0004\u0018\u00010\u0001H\u00d6\u0003\u00a2\u0006\u0004\u0008\u000f\u0010\u0010J\r\u0010\u0011\u001a\u00020\u0012\u00a2\u0006\u0004\u0008\u0013\u0010\u0014J\u0010\u0010\u0015\u001a\u00020\u0007H\u00d6\u0001\u00a2\u0006\u0004\u0008\u0016\u0010\u0009J\u0010\u0010\u0017\u001a\u00020\u0003H\u00d6\u0001\u00a2\u0006\u0004\u0008\u0018\u0010\u0005R\u0011\u0010\u0006\u001a\u00020\u00078F\u00a2\u0006\u0006\u001a\u0004\u0008\u0008\u0010\u0009R\u0011\u0010\u0002\u001a\u00020\u0003\u00a2\u0006\u0008\n\u0000\u001a\u0004\u0008\n\u0010\u000b\u0088\u0001\u0002\u00f8\u0001\u0000\u0082\u0002\u0004\n\u0002\u0008\u0019\u00a8\u0006\u0019"}, d2={"LName;", "", "s", "", "constructor-impl", "(Ljava/lang/String;)Ljava/lang/String;", "length", "", "getLength-impl", "(Ljava/lang/String;)I", "getS", "()Ljava/lang/String;", "equals", "", "other", "equals-impl", "(Ljava/lang/String;Ljava/lang/Object;)Z", "greet", "", "greet-impl", "(Ljava/lang/String;)V", "hashCode", "hashCode-impl", "toString", "toString-impl", "kotlin-demo"})

    // access flags 0x12
    private final Ljava/lang/String; s

    @groovyx.ast.bytecode.Bytecode
    public final String getS() {
    aload 0
    getfield 'Name.s','Ljava/lang/String;'
    areturn
    }

    @groovyx.ast.bytecode.Bytecode
    public final static int getLength-impl(String a) {
    aload 0
    invokevirtual 'java/lang/String.length','()I'
    ireturn
    }

    @groovyx.ast.bytecode.Bytecode
    public final static void greet-impl(String a) {
    _new 'java/lang/StringBuilder'
    dup
    invokespecial 'java/lang/StringBuilder.<init>','()V'
    ldc "Hello, "
    invokevirtual 'java/lang/StringBuilder.append','(Ljava/lang/String;)Ljava/lang/StringBuilder;'
    aload 0
    invokevirtual 'java/lang/StringBuilder.append','(Ljava/lang/String;)Ljava/lang/StringBuilder;'
    invokevirtual 'java/lang/StringBuilder.toString','()Ljava/lang/String;'
    getstatic 'java/lang/System.out','Ljava/io/PrintStream;'
    swap
    invokevirtual 'java/io/PrintStream.println','(Ljava/lang/Object;)V'
    return
    }

    @groovyx.ast.bytecode.Bytecode
    public static String toString-impl(String a) {
    _new 'java/lang/StringBuilder'
    dup
    invokespecial 'java/lang/StringBuilder.<init>','()V'
    ldc "Name(s="
    invokevirtual 'java/lang/StringBuilder.append','(Ljava/lang/String;)Ljava/lang/StringBuilder;'
    aload 0
    invokevirtual 'java/lang/StringBuilder.append','(Ljava/lang/String;)Ljava/lang/StringBuilder;'
    bipush 41
    invokevirtual 'java/lang/StringBuilder.append','(C)Ljava/lang/StringBuilder;'
    invokevirtual 'java/lang/StringBuilder.toString','()Ljava/lang/String;'
    areturn
    }

    @groovyx.ast.bytecode.Bytecode
    public String toString() {
    aload 0
    getfield 'Name.s','Ljava/lang/String;'
    invokestatic 'Name.toString-impl','(Ljava/lang/String;)Ljava/lang/String;'
    areturn
    }

    @groovyx.ast.bytecode.Bytecode
    public static int hashCode-impl(String a) {
    aload 0
    invokevirtual 'java/lang/String.hashCode','()I'
    ireturn
    }

    @groovyx.ast.bytecode.Bytecode
    public int hashCode() {
    aload 0
    getfield 'Name.s','Ljava/lang/String;'
    invokestatic 'Name.hashCode-impl','(Ljava/lang/String;)I'
    ireturn
    }

    @groovyx.ast.bytecode.Bytecode
    public static boolean equals-impl(String a,Object b) {
    aload 1
    _instanceof 'Name'
    ifne l0
    iconst_0
    ireturn
    l0
    aload 1
    checkcast 'Name'
    invokevirtual 'Name.unbox-impl','()Ljava/lang/String;'
    aload 0
    swap
    invokestatic 'kotlin/jvm/internal/Intrinsics.areEqual','(Ljava/lang/Object;Ljava/lang/Object;)Z'
    ifne l1
    iconst_0
    ireturn
    l1
    iconst_1
    ireturn
    }

    @groovyx.ast.bytecode.Bytecode
    public boolean equals(Object a) {
    aload 0
    getfield 'Name.s','Ljava/lang/String;'
    aload 1
    invokestatic 'Name.equals-impl','(Ljava/lang/String;Ljava/lang/Object;)Z'
    ireturn
    }

    @groovyx.ast.bytecode.Bytecode
    private void <init>(String a) {
    aload 0
    invokespecial 'java/lang/Object.<init>','()V'
    aload 0
    aload 1
    putfield 'Name.s','Ljava/lang/String;'
    return
    }

    @groovyx.ast.bytecode.Bytecode
    public static String constructor-impl(String a) {
    // annotable parameter count: 1 (invisible)
    aload 0
    ldc "s"
    invokestatic 'kotlin/jvm/internal/Intrinsics.checkNotNullParameter','(Ljava/lang/Object;Ljava/lang/String;)V'
    aload 0
    areturn
    }

    @groovyx.ast.bytecode.Bytecode
    public final static Name box-impl(String a) {
    _new 'Name'
    dup
    aload 0
    invokespecial 'Name.<init>','(Ljava/lang/String;)V'
    areturn
    }

    @groovyx.ast.bytecode.Bytecode
    public final String unbox-impl() {
    aload 0
    getfield 'Name.s','Ljava/lang/String;'
    areturn
    }

    @groovyx.ast.bytecode.Bytecode
    public final static boolean equals-impl0(String a,String b) {
    aload 0
    aload 1
    invokestatic 'kotlin/jvm/internal/Intrinsics.areEqual','(Ljava/lang/Object;Ljava/lang/Object;)Z'
    ireturn
    }
    }

    中缀函数

    1
    2
    3
    4
    5
    6
    7
    infix fun Int.shl(x: Int): Int { …… }

    // 用中缀表示法调用该函数
    1 shl 2

    // 等同于这样
    1.shl(2)

    中缀函数调用的优先级低于算术操作符、类型转换以及 rangeTo 操作符。

    尾递归函数

    作用域函数

  • let

    1
    2
    3
    4
    5
    6
    7
    fun main() {
    val person = Person("songpengfei",32,"beijing").let {
    it.age = 21
    it // 需要返回it
    }
    println(person.age) // let闭包中上下文是it
    }
  • run

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    fun main() {
    val person = Person("songpengfei", 32, "beijing").run {
    age = 21
    this // 需要返回it
    }
    println(person.age) // let闭包中上下文是this
    }

    fun main() {
    val person = run {
    val person = Person("songpengfei", 32, "beijing")
    person.age = 21
    person
    }
    println(person.age)
    }
  • apply

    1
    2
    3
    4
    5
    6
    fun main() {
    val person = Person("songpengfei", 32, "beijing").apply {
    age = 21
    }
    println(person.age) // 同run
    }
  • also

    1
    2
    3
    4
    5
    6
    fun main() {
    val person = Person("songpengfei", 32, "beijing").also {
    it.age = 21
    }
    println(person.age) // 同let
    }
  • with

    1
    2
    3
    4
    5
    6
    7
    fun main() {
    val p = with(Person("songpengfei", 32, "beijing")) {
    age = 21
    this
    }
    println(p)
    }
  • takeIf

    1
    2
    3
    4
    5
    6
    fun main() {
    val person = Person("songpengfei", 32, "beijing").takeIf {
    it.age != 32
    }
    println(person)
    }
  • takeUnless

    1
    2
    3
    4
    5
    6
    fun main() {
    val person = Person("songpengfei", 32, "beijing").takeUnless {
    it.age == 32
    }
    println(person)
    }

    解构声明

    1
    2
    3
    4
    5
    6
    data class Person(var name: String, var age: Int, var city: String)
    fun main() {
    val (name,age) = Person("song",32,"beijing")
    println(name)
    println(age)
    }

    image.png
    data类 会生成 componentN函数

    This 表达式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class A { // 隐式标签 @A
    inner class B { // 隐式标签 @B
    fun Int.foo() { // 隐式标签 @foo
    val a = this@A // A 的 this
    val b = this@B // B 的 this
    val c = this // foo() 的接收者,一个 Int
    val c1 = this@foo // foo() 的接收者,一个 Int
    val funLit = lambda@ fun String.() {
    val d = this // funLit 的接收者
    }
    val funLit2 = { s: String ->
    // foo() 的接收者,因为它包含的 lambda 表达式
    // 没有任何接收者
    val d1 = this
    }
    }
    }
    }

    注解

    1
    2
    3
    4
    5
    6
    annotation class Ann
    class Example(
    @field:Ann val foo: Int, // 标注 Java 字段
    @get:Ann val bar: Int, // 标注 Java getter
    @param:Ann val quux: Int
    )

    反射

    1
    implementation("org.jetbrains.kotlin:kotlin-reflect:1.7.20")

    KClasses 中定义了拓展反射方法

协程

1
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
  • runBlocking 方法会_阻塞_当前线程来等待
  • coroutineScope 只是挂起,会释放底层线程用于其他用途
  • runBlocking嵌套runBlocking ,被嵌套的runBlocking会让外部runBlocking阻塞
  • Dispatchers.Unconfined 不会受到限制,直接执行,如果块内部调用了delay,阻塞完成后会切换线程

委托属性

  • 延迟属性(lazy properties): 其值只在首次访问时计算;
  • 可观察属性(observable properties): 监听器会收到有关此属性变更的通知;
  • 把多个属性储存在一个映射(map)中,而不是每个存在单独的字段中。