Kotlin之精选

1 如何巧用Kotlin内置函数?

1.1 let、also、with、run、和apply区别?

在这里插入图片描述

1.2 until、step、downTo、in 等关键字

在这里插入图片描述

1.2 使用示例区别?

1.2.1 let

private fun higherFunCompare() {
        val people : People = People("chen", 1, listOf("x", "y"))

        /**
         * let
         * 作用:1.避免写判空的处理;2.使用it替代object对象在其作用域内访问属性&方法;3.返回值是最后一行 == return ...
         */
        val let = people?.let {
            it.age
            it.name
            it.isYong()
            it.isMen()
            999
        }
        LogUtils.d(TAG, "people?.let:$let")
        // people?.let:999

        // java
        if (people != null) {
            people.age
            people.name
            people.isYong()
            people.isMen()
            999
        }
    }

1.2.2 also

private fun higherFunCompare() {
        /**
         * also:类似let函数,但区别在于返回值:
         * 3.返回值是传入的对象的本身
         */
        val also = people?.also {
            it.age
            it.name
            it.isYong()
            it.isMen()
            999
        }
        LogUtils.d(TAG, "people?.also:$also")
        // people?.also:com.read.kotlinlib.model.People@1f24758d
    }

1.2.3 with

private fun higherFunCompare() {
        /**
         * with:
         * 1.调用同一个对象的多个方法/属性时,省去重复的对象名,直接调用方法名/属性即可;2.返回值是最后一行
         */
        val with = with(people) {
            LogUtils.d(TAG,"my name is $name, I am $age years old, ${isYong()}, ${isMen()}")
            999
        }
        LogUtils.d(TAG, "with(people):$with")
        // my name is chen, I am 1 years old, false, true
        // with(people):999

        // java
        LogUtils.d(TAG,"my name is $people.name, I am $people.age years old, ${people.isYong()}, ${people.isMen()}")
    }

1.2.4 run

private fun higherFunCompare() {        
        /**
         * run:结合了let、with两个函数的作用
         * 作用:1.避免写判空的处理;2.使用it替代object对象在其作用域内访问属性&方法;3.返回值是最后一行;
         *      4.调用同一个对象的多个方法/属性时,省去重复的对象名,直接调用方法名/属性即可
         */
        val run = people?.run {
            LogUtils.d(TAG,"my name is $name, I am $age years old, ${isYong()}, ${isMen()}")
            999
        }
        LogUtils.d(TAG, "people?.run:$run")
        // my name is chen, I am 1 years old, false, true
        // people?.run:999
    }

1.2.5 apply

private fun higherFunCompare() {
        /**
         * apply:与run函数类似,但区别在于返回值:
         * 3.返回值是传入的对象的本身;
         */
        val apply = people?.apply {
            LogUtils.d(TAG,"my name is $name, I am $age years old, ${isYong()}, ${isMen()}")
            999
        }
        LogUtils.d(TAG, "people?.apply:$apply")
        // my name is chen, I am 1 years old, false, true
        // people?.apply:com.read.kotlinlib.model.People@1f24758d
    }

1.3 参考链接

如何巧用Kotlin内置函数?

2 函数

// 函数返回一个Int类型的值。并且接受了一个block()函数作为该函数的参数;
// 其中block()接受一个Char类型的参数,并且返回一个Int类型的值,默认值是一个返回值为1的代码块:{1}

// sumBy函数参数是一个扩展在CharSequence类型下的函数,
// 同理block()函数参数也是一个扩展在CharSequence类型下的函数,可以缩写;
fun CharSequence.sumBy(block: CharSequence.(char: Char) -> Int = { 1 }): Int { 
    // == CharSequence.sumBy(block: (Char) -> Int): Int {
}
// block 本身是一个函数
// 当一个函数被内联 inline 标注后,在调用它的地方,会把这个函数方法体中的所以代码移动到调用的地方,而不是通过方法间压栈进栈的方式,从而使得方法的调用栈少一层
// 应该使用 inline 的地方: 带有 lambda 参数的函数
inline fun measure(block: () -> Unit): Long {
    val start = System.currentTimeMillis()
    block()
    return System.currentTimeMillis() - start
}

// 当不添加 inline 时,代码中,多出了一个类,增加内存的分配;
// 类是:com/read/kotlinlib/basic/CoroutineActivity$testBlock$4.INSTANCE : Lcom/read/kotlinlib/basic/CoroutineActivity$testBlock$4
inline fun measureStr(block: (str: String) -> Unit): Long {  // == fun measureStr(block: (String) -> Unit): Long {
    val start = System.currentTimeMillis()
    block("measureStr")
    return System.currentTimeMillis() - start
}

3 for循环

    // 正序遍历
    for (index in 0..10){
    	print(index) //输出012345678910
    }
   
    // 倒序遍历
    for (index in 10 downTo 1){
    	print(index) //输出10987654321
    }
   
    // 不使用1作为遍历的步长
    for (index in 0..10 step 2){
    	print(index) //输出0246810
    }
  
    // 一个不包含末尾元素的区间:
    for (index in 0 until 10){
    	print(index) //输出0123456789
    }
   
    // 遍历一个数组/列表,想同时取出下标和元素:
    val arrays = arrayOf("a", "b", "c")
    for ((index,e) in arrays.withIndex()){
    	print("下标=$index--元素=$e") //输出下标=0--元素=a 下标=1--元素=b 下标=2--元素=c
    }
 
    // 遍历一个数组/列表,只取出下标:
    for (index in arrays.indices){
    	print("index=$index") //输出index=0 index=1 index=2
    }
   
    // 遍历取元素:
    for (element in arrays){
    	print("element=$element") //输出element=a element=b element=c
    }

参考链接:kotlin for循环的几种使用方法

4 变量

4.1 const val 和val修饰对象的主要区别

const val 可见性为public final static,可以直接访问。
val 可见性为private final static,并且val 会生成方法getNormalObject(),通过方法调用访问。

4 单例最佳写法

class SingletonDemo private constructor() {
    companion object {
        val instance: SingletonDemo by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
        SingletonDemo() }
    }
}
class SingletonDemo private constructor() {
    companion object {
        val instance = SingletonHolder.holder
    }

    private object SingletonHolder {
        val holder= SingletonDemo()
    }
}
companion object {
        @Volatile
        private var instance: DiscoveryRepository? = null

        fun getInstance() = run {
            instance ?: synchronized(this) {
                instance ?: DiscoveryRepository().also { instance = it }
            }
        }
    }

5 Java中调用Kotlin会遇到的坑?

5.1 @JvmField

var mWaitingDialog: WaitingDialog? = null

在这里插入图片描述
在这里插入图片描述

@JvmField  
var mWaitingDialog: WaitingDialog? = null

@JvmField 将Kotlin属性作为字段暴露,使用@JvmField注解对其标注。该字段将具有与底层属性相同的可见性。否则,通过getMWaitingDialog(),kotlin会默认生成get\set方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值