栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Kotlin 常用API汇总

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Kotlin 常用API汇总

前言

本文汇总kotlin里常用API、基础知识,会持续更新,便于查阅。

kotlin中文站

equals()和hashCode()方法
  1. Kotlin 中的== 等同于调用 equals() 函数,比较两个对象引用是否相等要用 === 操作符。
  2. 用 ==操作符时不需要担心空安全,a == b 等同于 a?.equals(b) ?: b == null。
  3. 和Java一样,复写equals()方法同样遵循复写equals()方法遵守的约定,需要同时复写hashCode()方法。
public open class Any public constructor() {
    public open operator fun equals(other: kotlin.Any?): kotlin.Boolean {  }
    public open fun hashCode(): kotlin.Int {  }
    public open fun toString(): kotlin.String {  }
}
lateinit、lazy、getter()
private lateinit var mViewMoudule: ViewModuleImpl;
private val mLiveData by lazy { MutableLiveData() }
val textView: TextView
    get() = findViewById(R.id.tv_sth)
  • lateinit 关键字
    变量在定义时不需要初始化,所以在使用变量时,不需要加上 ? 和 !! 操作符。
    但是在使用第一次变量之前,一定要保证为它赋值 , 不然会出现空指针异常。

  • by lazy
    在第一次使用该变量时会进行赋值;
    十分适合加载可能访问或不可访问的变量。

  • get() 函数
    每次调用该变量时,即相当于调用get()函数,适合Bean属性的获取,不适合复杂赋值等变量

扩展函数、全局函数、内联函数
  • 扩展函数

    1. Kotlin 能够扩展一个类的新功能而无需继承该类或者使用像装饰者这样的设计模式。 这通过叫做 扩展 的特殊声明完成。 这种机制称为 扩展函数 。此外,也有 扩展属性 ,
    2. 扩展不能真正的修改他们所扩展的类。通过定义一个扩展,你并没有在一个类中插入新成员, 仅仅是可以通过该类型的变量用点表达式去调用这个新函数。
    3. 扩展函数是静态分发的,即他们不是接收者类型的虚方法。 这意味着调用的扩展函数是由函数调用所在的表达式的类型来决定的, 而不是由表达式运行时求值结果决定的。即静态绑定的,非动态运行时类型推断的,无虚表替换。
    4. 如果一个类定义有一个成员函数与一个扩展函数,而这两个函数又有相同的接收者类型、 相同的名字,并且都适用给定的参数,这种情况总是取成员函数。
  • 全局函数

    1. 全局函数的作用域是以包为作用域的;
    2. 引入的时候可以直接使用import xxx.全局函数,这个跟java的不同;
    3. 也就是同一个包作用域下,不可以有“同名”的全局函数;
    4. 如果不同的包作用域下,有“同名”的全局函数,则需要引入全局函数的全局路径即可;
  • 内联函数

    1. 添加inline关键字使函数成为内联函数,inline 修饰符影响函数本身和传给它的 lambda 表达式,所有这些都将内联到调用处;
    2. 内联可能导致生成的代码增加,好好使用这个功能;
    3. 可以添加noinline修饰符标记不希望内联的函数参数;
    4. inline在kotlin这里是真的内联的,但是在cpp里是建议编译器进行优化,注意一下这块。

例如如下例子:

// 对MutableList进行扩展,添加swap函数。
fun  MutableList.wap(index1: Int, index2: Int) {
    val tmp = this[index1] // “this”对应该列表
    this[index1] = this[index2]
    this[index2] = tmp
}

// 封装lock inline函数
inline fun  lock(lock: Lock, block: () -> T): T { 
	lock.lock()
	try {
	    block()
	} finally {
	    lock.unlock()
	}
}
作用域函数:let、apply、also、run、with

在使用这些内联函数,要特别注意返回值,避免使用错误。有些很相近,而内部的代码块中接收者是 this 或 it。
可能有点类似语义上的区别了,之后在使用的过程中再熟悉总结吧,最常用还是let和apply了。

函数对象引用返回值是否是扩展函数
letitLambda 表达式结果
runthisLambda 表达式结果
withthisLambda 表达式结果不是:把上下文对象当做参数
applythis上下文对象
alsoit上下文对象
  • let
    let常用的场景就是使用let函数判空处理,在let闭包下不用写繁琐的问号了。
var list: List? = null
list?.let {
	// 不空位的情况
} ?: let {
	// 为空的情况
}


var list: List? = mutableListOf()
val let = list?.let {
     it.size	// 最后一行返回值
}

public inline fun  T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)  // 返回闭包
}
  • apply
    apply一般用于对象实例初始化的时候,使用apply初始化对象的各种属性,或者直接调用对象方法进行初始化。
var map = HashMap().apply {
	put("key", "value")
}
var view = TextView(this).apply { id = R.id.textView }
        
public inline fun  T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this  // 返回对象本身
}
  • run、with、also
    • with可以用于UI数据绑定实体,返回闭包最后一行数据,但是user为null时实用性不如let;
    • run返回闭包结果,传入的是this,主要目的是强调需要执行的函数
    • also返回调用对象本身,also 就像 apply :它接受接收者、做⼀些动作、并返回该接收者。 ⼆者区别是在apply 内部的代码块中接收者是 this,⽽在 also 内部的代码块中是 it。
var user: User? = null;
var result = with(user, {
	tv_name.text = this?.name
	"${this?.name}, ${this?.age}"	// 返回闭包最后一行
})

// 从intent取key_extra的值,不为非空且内容不为空,赋值给url。否则弹出提示并关闭页面。
var url = intent.getStringExtra("key_extra")?.takeIf { it.isNotEmpty() } ?: run {
    Log.e("mLogU", "null url")
    finish()
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/820554.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号