Kotlin学习笔记

 

Kotlin中的高级运算符

  • ?: 猫王运算符,是三元运算符的简化版本,?:省略了左侧的部分,当问号左侧的表达式notnull时返回左侧表达式,否则返回?:右侧的表达式,是a != null ? a : b写法的语法糖

  • ::双冒号操作符,表示将方法当作参数,传递到另一个方法中进行使用,引用一个方法

    fun main(args: Array<String>) {
        println(lock("param1", "param2", ::getResult))
    }
    fun getResult(str1: String, str2: String): String = "result is {$str1 , $str2}"
    fun lock(p1: String, p2: String, method: (str1: String, str2: String) -> String): String {
        return method(p1, p2)
    }
    

Kotlin中的高阶函数

  • 高阶函数可以不用定义接口使用回调,使用起来更加灵活

    //定义
    fun pay(block: (String) -> Unit) {
            println("before block")
    		//这里的block就是方法传入参数block
            block("支付宝")
            println("end block")
        }
    //调用
    pay{
        println("高阶函数..it=$it")
    }
    //结果
    //before block
    //高阶函数..it=支付宝
    //end block
    

Kotlin中的标准库函数

  • let:将 调用它的对象 作为参数 并返回lambda的结果

    • 他是一个作用域函数,在表达式内部声明的变量不能在外部使用

    • it关键字与let对应的,是使用let调用对象的副本

    •     var str = "Hello World"
          str.let { println("$it!!") }
          println(str)
          //输出
          //Hello World!!
          //Hello World
      
    • 嵌套let不能使用it关键字

    • let是空安全的,当属性不为null时,才会执行let表达式中的代码
  • run:与let相同,但是可以改变外部属性

    • 不支持it关键字

    • 	var tutorial = "This is Kotlin Tutorial"
          println(tutorial) //This is Kotlin Tutorial
          tutorial = run {
              val tutorial = "This is run function"
              tutorial
          }
          println(tutorial) //This is run function
      
  • also:对调用对象进行了一些额外的处理

    • 与let不同,also返回原始对象 而不是新的对象,对原始对象的操作会被保留

    • var m = 1
      m = m.also { it + 1 }.also { it + 1 }
      println(m) //prints 1 
      
    • 区别letalso also 表达式返回数据类对象,而 let 表达式不返回任何内容 (Unit),因为我们没有明确指定任何内容。

      data class Person(var name: String, var tutorial : String)
      var person = Person("Anupam", "Kotlin")
          
      var l = person.let { it.tutorial = "Android" }
      var al = person.also { it.tutorial = "Android" }
              
      println(l)//kotlin.Unit
      println(al)//Person(name=Anupam,tutorial= "Android")
      println(person)//Person(name=Anupam,tutorial= "Android")
      
  • apply:是一个类型的拓展函数

    • 在引用对象运行到表达式中,并在运行完成时返回对象引用

    • data class Person(var name: String, var tutorial : String)
      var person = Person("Anupam", "Kotlin")
          
      person.apply { this.tutorial = "Swift" }
      println(person) // Person(name="Anupam", tutorial="Swift")
      
    • applyalso的区别 applyit关键字是不允许的.如果引用的数据类的属性名在函数中是唯一的,可以省略this

      data class Person(var n: String, var t : String)
      var person = Person("Anupam", "Kotlin")
          
      person.apply { t = "Swift" }
      println(person)//Person(name="Anupam", tutorial="Swift")
          
      person.also { it.t = "Kotlin" }
      println(person)//Person(name="Anupam", tutorial="Kotlin")
      
  • with:就像是apply一样,with用于更改实例属性,调用时无需使用.运算符

    • data class Person(var name: String, var tutorial : String)
      var person = Person("Anupam", "Kotlin")
          
      with(person)
          {
              name = "No Name"
              tutorial = "Kotlin tutorials"
          }
      println(person)//Person(name="No Name", tutorial="Kotlin tutorials")
      
    • withapply的区别

      • apply需要接收器,也就是需要基于对象调用, with可以独立调用
      • with函数的最后一个表达式可以返回一个return

Tips:

  • 如果要在抽象类中创建一个可以重写或不重写的抽象方法,需要这样写

      open fun initEvent() {}
    
  • kotlin有内部类和嵌入类的区别,如果需要创建内部类,需要标记inner 嵌入类添加该参数可以访问外部类的属性和方法,带有对外部类的引用
    • 添加inner非静态内部类
    • 不添加inner的正常内部类是静态的
  • @JvmStatic该注解可以用在companion object伴生方法中,作用是在使用java调用kotlin时,可以保持原生的调用方式

      BigInteger bigInteger = TestStatic.Companion.getBIG_INTEGER();//没使用@JvmStatic
      BigInteger bigInteger = TestStatic.BIG_INTEGER;//使用了@JvmStatic
    
  • 适配Android12的话,调用api版本如果是31,需要对activity或者receiver,service声明android:exported=”false”,不然会无法安装app