Kotlin学习笔记1

数组

kotlin 复制代码
/**
 * 何时使用数组
 */
fun useDemo() {
    // Kotlin 中最常见的数组类型是对象类型数组,由 Array 类表示。
    // 如果在对象类型数组中使用原生类型,那么会对性能产生影响,因为原生值都装箱成了对象。 为了避免装箱开销,请改用原生类型数组。
    var strArray = arrayOf("At", "Brod", "Cak")
    // 使用 += 赋值操作创建了一个新的 riversArray,复制了原始元素并添加新元素
    strArray += "Dart"
    println(strArray.joinToString("-"))
}

/**
 * 创建数组
 * arrayOf()  arrayOfNulls()  emptyArray() and Array constructor.
 */
fun arrayDemo() {
    val arr1 = arrayOf(1, 2, 3, 4, 5, 6)
    println(arr1.joinToString())

    val nullArray: Array<Int?> = arrayOfNulls(3)
    println(nullArray.joinToString())

    var exampleArray = emptyArray<String>()
    var exampleArray2: Array<String> = emptyArray()
}

fun arrayDemo2() {
    // Creates a two-dimensional array
    val twoDArray = Array(2) { Array<Int>(2) { 0 } }
    println(twoDArray.contentDeepToString())
    // [[0, 0], [0, 0]]

    // Creates a three-dimensional array
    val threeDArray = Array(3) { Array(3) { Array<Int>(3) { 0 } } }
    println(threeDArray.contentDeepToString())
}

/**
 * 访问与修改元素
 */
fun operatorDemo() {
    val intArray = arrayOf(1, 2, 3)
    intArray[0] = 10
    println(intArray.joinToString())
}

fun printAllStrings(vararg strings: String) {
    for (string in strings) {
        print(string)
    }
}

fun varargDemo() {
    val lettersArray = arrayOf("c", "d")
    printAllStrings("a", "b", *lettersArray)
    println()
}

/**
 * 将数组转换为集合
 */

fun toListDemo() {
    val simpleArray = arrayOf("a", "b", "c", "c")
    println(simpleArray.toSet())
    println(simpleArray.toList())

    val pairArray = arrayOf("apple" to 120, "banana" to 150, "cherry" to 90, "apple" to 140)
    println(pairArray.joinToString())
    println(pairArray.toMap())

}

/**
 * BooleanArray	boolean[]
 * ByteArray	byte[]
 * CharArray	char[]
 * DoubleArray	double[]
 * FloatArray	float[]
 * IntArray	    int[]
 * LongArray	long[]
 * ShortArray	short[]
 */
fun arrayDemo3() {
    val exampleArray = IntArray(5)
    println(exampleArray.joinToString())
}

fun main() {
//    useDemo()
//    arrayDemo()
    arrayDemo2()
    operatorDemo()
    varargDemo()
    toListDemo()
}

类型检测和类型转换

kotlin 复制代码
package com.mcc.myapplication

fun getNum(): Number {
    return 100F
}

/**
 * is 与 !is 操作符
 */
fun isDemo() {
    val obj = "hello"
    if (obj is String) {
        println("string length:${obj.length}")
    }
    val value = 1
    if (value is Int) {
        println("$value is Int")
    }
    val num = getNum()
    if (num !is Int) {
        println("$num not is Int")
    }
}

/**
 *  智能转换
 */
fun transferDemo(x: Any) {
    if (x is String) {

        println("this param is string, and length:${x.length}") // x 自动转换为字符串
    }
}

fun transferDemo2(x: Any) {
    if (x !is String) return
    // 如果反向检测导致返回那么该转换是安全的
    println("this param is string, and length:${x.length}")
}

fun transferDemo3(x: Any) {
    // `||` 右侧的 x 自动转换为 String
    if (x !is String || x.length == 0) return

    // `&&` 右侧的 x 自动转换为 String
    if (x is String && x.length > 0) {
        println("this param is string, and length:${x.length}")
    }
}

fun transferDemo4(x: Any) {
    when (x) {
        is Int -> print(x + 1)
        is String -> print(x.length + 1)
        is IntArray -> print(x.sum())
    }
}

fun transferDemo5(x: Any) {
    // "不安全的"转换操作符
    val y: String? = x as String?
    if (y != null) {
        println("this param is string, and length:${x.length}")
    }
}

fun transferDemo6(x: Any) {
    // "安全的"(可空)转换操作符
    val y: String? = x as? String
    if (y != null) {
        println("this param is string, and length:${x.length}")
    }
}

fun main() {
    isDemo()
    transferDemo("world")
    transferDemo2("gogogo")
    transferDemo3("pythonX")
    transferDemo4(intArrayOf(1, 2, 3, 4, 5))
    transferDemo4(arrayOf(1, 2, 3, 4, 5, 6))
//    transferDemo5(111)
    transferDemo6(111)
}

If 表达式

kotlin 复制代码
fun main() {
    val a = 2
    val b = 3
    var max: Int? = null
    if (a > b) {
        max = a
    } else {
        max = b
    }
    // 作为表达式
    max = if (a > b) a else b
    println("max is $max")

    val c = 10
    val maxOrLimit = if (c > a) c else if (a > b) a else b
    println("maxOrLimit is $maxOrLimit")

    // if 表达式的分支可以是代码块,这种情况最后的表达式作为该块的值
    val max2 = if (a > b) {
        print("Choose a,")
        a
    } else {
        print("Choose b,")
        b
    }
    println("max2 is $max2")
}

When 表达式

kotlin 复制代码
fun whenDemo1(x: Int) {
    when (x) {
        1 -> print("x == 1")
        2 -> print("x == 2")
        else -> {
            print("x=$x is neither 1 nor 2")
        }
    }
    println()
}

enum class Bit {
    ZERO, ONE, TWO
}

fun getRandomBit(): Bit {
    return Bit.ZERO
}

fun whenDemo2() {
    val numericValue = when (getRandomBit()) {
        Bit.ZERO -> 0
        Bit.ONE -> 1
        Bit.TWO -> 2
        // 'else' is not required because all cases are covered
    }
    println(numericValue)
}

fun whenDemo3(x: Int, s: String) {
    when (x) {
        0, 1 -> print("x == 0 or x == 1")
        else -> print("otherwise")
    }

    when (x) {
        s.toInt() -> print("s encodes x")
        else -> print("s does not encode x")
    }

    val validNumbers = listOf(3, 4, 5)
    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")
    }
}

fun main() {
    whenDemo1(3)
    whenDemo2()
}

For 循环

kotlin 复制代码
fun main() {
    // for 循环可以对任何提供迭代器(iterator)的对象进行遍历
    val ints = listOf(2, 3, 4, 5, 6)
    for (item: Int in ints) {
        print(item)
    }
    println()

    for (i in 1..3) {
        print(i)
    }
    println()
    for (i in 6 downTo 0 step 2) {
        print(i)
    }
    println()

    val array = arrayOf("a", "b", "c")
    for (i in array.indices) {
        print(array[i])
    }
    println()
    for ((index, value) in array.withIndex()) {
        println("the element at $index is $value")
    }
}

while 循环

kotlin 复制代码
while (x > 0) {
    x--
}

do {
  val y = retrieveData()
} while (y != null) // y 在此处可见

返回与跳转

kotlin 复制代码
/**
 * 在 Kotlin 中任何表达式都可以用标签来标记。 标签的格式为标识符后跟 @ 符号
 */
fun demo1() {
    loop@ for (i in 1..100) {
        for (j in 1..100) {
            if (j > 1) break@loop
            println(j)
        }
    }
}

/**
 * 返回到标签
 */
fun demo2() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return // 非局部直接返回到 demo2() 的调用者
        print(it)
    }
    println("this point is unreachable")
}

fun demo3() {
    listOf(1, 2, 3, 4, 5).forEach lit@{
        if (it == 3) return@lit // 局部返回到该 lambda 表达式的调用者------forEach 循环
        print(it)
    }
    print(" done with explicit label")
}

fun demo4() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return@forEach // 局部返回到该 lambda 表达式的调用者------forEach 循环
        print(it)
    }
    print(" done with implicit label")
}

fun demo5() {
    listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
        if (value == 3) return  // 局部返回到匿名函数的调用者------forEach 循环
        print(value)
    })
    print(" done with anonymous function")
}

fun main() {
    demo5()
}

异常

kotlin 复制代码
/**
 * try {
 *     // 一些代码
 * } catch (e: SomeException) {
 *     // 处理程序
 * } finally {
 *     // 可选的 finally 块
 * }
 */

fun fail(message: String): Nothing {
    throw IllegalArgumentException(message)
}

fun main(){
    val input = "2"
    val a: Int? = try { input.toInt() } catch (e: NumberFormatException) { null }
}

包与导入

kotlin 复制代码
package com.mcc.myapplication

fun printMessage() { /*......*/
}

class Message { /*......*/ }

/**
 * 源文件所有内容(无论是类还是函数)都包含在该包内。
 * 所以上例中 printMessage() 的全名是 org.example.printMessage,
 * 而 Message 的全名是 org.example.Message
 */

/**
 * 默认导入
 * 有多个包会默认导入到每个 Kotlin 文件中:
 * kotlin.*
 * kotlin.annotation.*
 * kotlin.collections.*
 * kotlin.comparisons.*
 * kotlin.io.*
 * kotlin.ranges.*
 * kotlin.sequences.*
 * kotlin.text.*
 *
 * JVM:
 * java.lang.*
 * kotlin.jvm.*
 *
 * 如果出现名字冲突,可以使用 as 关键字在本地重命名冲突项来消歧义:
 * import org.example.Message // Message 可访问
 * import org.test.Message as TestMessage // TestMessage 代表"org.test.Message"
 *
 * 关键字 import 并不仅限于导入类;也可用它来导入其他声明:
 * 顶层函数及属性
 * 在对象声明中声明的函数和属性
 * 枚举常量
 */

fun main() {

}

类与构造函数

kotlin 复制代码
package com.mcc.myapplication

import javax.inject.Inject

class Person { /*......*/ }

class Empty

class Student constructor(firstName: String) { /*......*/ }
// 如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字
// class Student(firstName: String) { /*......*/ }

class Customer public @Inject constructor(name: String) { /*......*/ }
// 如果构造函数有注解或可见性修饰符,这个 constructor 关键字是必需的

class InitOrderDemo(name: String) {
    val firstProperty = "First property: $name".also(::println)

    init {
        println("First initializer block that prints $name")
    }

    val secondProperty = "Second property: ${name.length}".also(::println)

    init {
        println("Second initializer block that prints ${name.length}")
    }
}

class Person2(val firstName: String, val lastName: String, var age: Int)

class Person3(val firstName: String, val lastName: String, var isEmployed: Boolean = true)

// 次构造函数
class Person4(val pets: MutableList<Pet> = mutableListOf())

class Pet {
    constructor(owner: Person4) {
        owner.pets.add(this) // adds this pet to the list of its owner's pets
    }
}

class Person5(val name: String) {
    val children: MutableList<Person5> = mutableListOf()

    // 如果类有一个主构造函数,每个次构造函数需要委托给主构造函数,
    // 可以直接委托或者通过别的次构造函数间接委托
    // 委托到同一个类的另一个构造函数用 this 关键字即可
    constructor(name: String, parent: Person5) : this(name) {
        parent.children.add(this)
    }
}

class Constructors {
    init {
        println("Init block")
    }

    constructor(i: Int) {
        println("Constructor i=$i")
    }

    constructor(i: Int, ss: String) : this(i) {
        println("Constructor ss=$ss")
    }

}

// 如果一个非抽象类没有声明任何(主或次)构造函数,它会有一个生成的不带参数的主构造函数。构造函数的可见性是 public。
class DoCreateMe private constructor() { /*......*/ }

// 如果你不希望你的类有一个公有构造函数,那么声明一个带有非默认可见性的空的主构造函数
class DonotCreateMe private constructor() { /*......*/ }

// 如果主构造函数的所有的参数都有默认值,编译器会生成一个额外的无参构造函数
class Customer2(val name: String = "", val age: Int = 18)

fun main() {
    val p = Person()
    val e = Empty()
    val s = Student("SnZ")
    InitOrderDemo("YourName")
    Person2("morning", "cat", 30)
    Person3("morning", "cat")
    val p4 = Person4()
    Pet(p4)
    Pet(p4)
    p4.pets.toList().joinToString().also(::println)
    val p5 = Person5("ZhangSan")
    Person5("ZhangXiao", p5)
    Constructors(33, "mcc")
    Customer2()
}

抽象类

kotlin 复制代码
// 类以及其中的某些或全部成员可以声明为 abstract
abstract class Polygon {
    abstract fun draw()
}

class Rectangle : Polygon() {
    override fun draw() {
        // draw the rectangle
    }
}

// 可以用一个抽象成员覆盖一个非抽象的开放成员
open class Polygon2 {
    open fun draw() {
        // some default polygon drawing method
    }
}

abstract class WildShape : Polygon2() {
    // Classes that inherit WildShape need to provide their own
    // draw method instead of using the default on Polygon
    abstract override fun draw()
}

类的继承

kotlin 复制代码
package com.mcc.myapplication

// 在 Kotlin 中所有类都有一个共同的超类 Any,对于没有超类型声明的类它是默认超类
class Example : Any() // 从 Any 隐式继承

// 默认情况下,Kotlin 类是最终(final)的------它们不能被继承。 要使一个类可继承,请用 open 关键字
open class Base(p: Int) // 该类开放继承

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

// 如果派生类没有主构造函数,那么每个次构造函数必须使用super 关键字初始化其基类型
class MyClass : Base {
    constructor(ctx: Int) : super(ctx)

    constructor(ctx: Int, name: String) : super(ctx)
}

// Kotlin 对于可覆盖的成员以及覆盖后的成员需要显式修饰符
open class Shape {
    open val vertexCount: Int = 0

    open fun draw() { /*......*/
    }

    // 如果函数没有标注 open 如 Shape.fill(),那么子类中不允许定义相同签名的函数
    fun fill() { /*......*/
    }
}

class Circle() : Shape() {
    override fun draw() { /*......*/
    }
}

// 将 open 修饰符添加到 final 类(即没有 open 的类) 的成员上不起作用

// 标记为 override 的成员本身是开放的,因此可以在子类中覆盖。如果你想禁止再次覆盖, 使用 final 关键字
open class Rectangle() : Shape() {

    // 属性与方法的覆盖机制相同。在超类中声明然后在派生类中重新声明的属性必须以 override 开头,并且它们必须具有兼容的类型。
    override val vertexCount = 4

    final override fun draw() { /*......*/
    }
}

interface Shape2 {
    val vertexCount: Int
}

class Rectangle2(override val vertexCount: Int = 4) : Shape2 // 总是有 4 个顶点

class Polygon2 : Shape2 {
    override var vertexCount: Int = 0  // 以后可以设置为任何数
}

// 派生类初始化顺序


// 调用超类实现


// 覆盖规则

fun main() {

}

类的属性

kotlin 复制代码
相关推荐
FunnySaltyFish8 小时前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
Kapaseker14 小时前
Compose 进阶—巧用 GraphicsLayer
android·kotlin
Kapaseker1 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
A0微声z3 天前
Kotlin Multiplatform (KMP) 中使用 Protobuf
kotlin
alexhilton4 天前
使用FunctionGemma进行设备端函数调用
android·kotlin·android jetpack
lhDream4 天前
Kotlin 开发者必看!JetBrains 开源 LLM 框架 Koog 快速上手指南(含示例)
kotlin
RdoZam4 天前
Android-封装基类Activity\Fragment,从0到1记录
android·kotlin
Kapaseker5 天前
研究表明,开发者对Kotlin集合的了解不到 20%
android·kotlin
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
starlaky5 天前
Django入门笔记
笔记·django