0
点赞
收藏
分享

微信扫一扫

kotlin语法糖

松鼠树屋 2021-09-29 阅读 74
Android

kotlin

  • with

    fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
    

    with方法传一个参数和一个lambda 拥有第一个参数的上下文环境 返回最后一行

    with的方式和apply还有let不一样 是方法 不是扩展 感觉是apply和let的组合体

  • apply

    fun <T> T.apply(f: T.() -> Unit): T { f(); return this }
    

    调用某对象的apply方法 在函数范围内 可以调用任意这个对象的方法 并将这个对象返回

  • run

    fun <T, R> T.run(f: T.() -> R): R = f()
    

    和apply很像 不过返回的是最后一行 而不是当前对象 和let区别 闭包没有参数 可以使用this

  • let

    fun <T, R> T.let(f: (T) -> R): R = f(this)
    

    调用某对象的let方法 会将该对象传入函数体重 it调用 返回值是函数的最后一行

  • inline

    将函数体直接拷贝到调用处 减少函数调用 一般内联函数都很短

    内联的函数在编译的时候会被进行代码替换 因此没有函数属性 所以内联函数只允许传递给内联函数

    内联函数可以执行return 而非内联只能进行局部返回

  • noline

    声明不会内联

  • crossline

    解决匿名函数不允许return 内联函数允许return 互相冲突导致 所以加上crossline关键字表示一定不会使用return关键字

  • data class

    数据类 会自动生成equals toString等方法

  • sealed class

    密封类 when方法必须实现所有的case

  • object class

    单例类

  • compain object{}

    伴生对象

  • operator fun plus(obj:Obj):Obj{}

    重载函数 重载Obj的plus方法

  • 高阶函数

    高阶函数加上inline是个好习惯

    fun operateNums(num1: Int, num2: Int, operate: (Int, Int) -> Int): Int {
        return operate(num1, num2)
    }
    
    fun StringBuilder.build(block: StringBuilder.() -> Unit): StringBuilder {
         block()
         return this
    }
    
    
  • 泛型

    • 泛型类

      class MyClass<T> {
          fun method(params: T): T {
          return params
         }
      }
      
      val myclass = MyClass<Int>()
      
    • 泛型方法

      class MyClass {
          fun <T> method(params: T): T {
          return params
      }
      }
      
      val result = MyClass().method(123)
      
  • by 委托

    可以将方法实现交给by后面的对象 这样我们可以将大部分方法交给委托对象实现 少部分需要我们自定义的或者需要修改的对象自己实现

    class MySet<T>(helpSet: HashSet<T>) : Set<T> by helpSet {}  
    
    
  • infix

    infix 不能定义成顶层函数 必须是某个类的成员函数 必须接收且只能接收一个参数
    例如 in to 等

    infix fun <T> Collection<T>.has(element: T): Boolean = contains(element)
    
    
  • 泛型实化(reified)

    • 泛型擦除

      在jvm中 所有的泛型都可以被称为假泛型 因为在编译的过程中 所有的泛型都会被擦除成object对象 在运行时再反射

      但是kotlin中提供了内联函数的功能 在调用时 会将方法体直接拷贝到调用处 这样也就不存在擦除的问题了 直接泛型实化了 使用关键字reified

    在刚开始看kotlin的时候 发现跳转Activity都需要T::class.java 感觉太麻烦了 根本不是一个高级语法糖语言该有的状态

    inline fun <reified T> startActivity(context: Context) {
        val intent = Intent(context, T::class.java)
        context.startActivity(intent)
    }
    
    startActivity<SettingsActivity>(this)
    
    
  • 泛型的协变和逆变

    • 协变

      我们在使用的java的时候 经常遇到一个问题

      Student类继承Person类

      List<Student> 传递给List<Person> 会报错 因为存在安全隐患 Student是Person的子类

      但是List<Student> 不是List<Person>的子类

      而协变的定义就是 当A是B的子类时 MyClass<A> 也是MyClass<B>的子类 就称为泛型的协变(关键字 out)

      class SimpleData<out T>(val data: T?) {}
      

      意味着我们只能对data进行读取操作 而不能改变data对象 因此也就不能用set方法进行赋值了

    • 逆变

      从定义上看 逆变的定义和协变完全相反 当A是B的子类时 MyClass<B>MyClass<A>的子类 就称为泛型的逆变(关键字 in)

  • suspend

    将一个函数声明为挂起函数 挂起函数之间都是可以互相调用的

  • coroutineScope

    继承外部协程作用域并创建一个子协程作用域 在其作用域内的所有代码和子协程全部执行完之前 会一直阻塞当前协程 coroutineScope只能在协程作用于中或者挂起函数中使用

举报

相关推荐

0 条评论