美文网首页
Kotlin(run,apply)陷阱

Kotlin(run,apply)陷阱

作者: MicroCoder | 来源:发表于2019-03-19 11:46 被阅读0次

    前一段时间跟一个朋友聊天聊到run,apply里面有一个隐蔽的陷阱,记录下来,前车之鉴,后车之师

    泛型T

    首先我们先看一下apply的源码

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

    这个泛型T可以为null,也就是说null也被赋予了apply的方法

    null.apply{
        System.out.println("null apply")
    }
    

    在IDE里面null是没有.apply方法提示的,可是在kotlin编译里面是可以通过

    null埋藏的陷阱

    由于null也有apply方法,所以对一个可空的对象(A)进行apply的话,block块是被执行的。如果A的方法与全局方法有重名的时候就会调用全局的方法。

    open class A {
        override fun toString(): String {
            return "this is A"
        }
    
        open fun methodPrint() {
            System.out.println("A print")
        }
    }
    
    class B {
        override fun toString(): String {
            return "this is B"
        }
    
        fun methodPrint() {
            System.out.println("B print")
        }
    
        fun print() {
            val a: A? = null
            System.out.println(a.apply {
                methodPrint()
                System.out.println("a.apply:" + toString())
            })
        }
    }
    

    输出

    B print
    a.apply:null
    null
    

    如果B还有继承关系那么就更加的隐蔽

    class C : A(){
        override fun toString(): String {
            return "this is C"
        }
    
        fun print() {
            val a: A? = null
            System.out.println(a.apply {
                methodPrint()
                System.out.println("a.apply:" + toString())
            })
        }
    }
    

    输出

    A print //此处打印的是C类的methodPrint()方法继承于A
    a.apply:null
    null
    

    T泛型的扩展

    利用泛型的扩展我可以封装一个nullwork方法,就是一个对象为空时执行nullblock,如果对象不为空时执行noNullblock。

    inline fun <T, R> T?.nullWork(noNull: (T) -> R, isNull: () -> R): R {
        return this?.let {
    //这里还有一个坑,就是如果block返回null还是会执行isNull()方法所以要使用return
            return noNull(it) 
        } ?: isNull()
    }
    

    总结

    陷阱的关键点有2个

    1. null对象有apply方法导致null对象的apply的block块是被执行的
    2. blcok块可以调用全局方法

    前车之鉴,后车之师,大家共勉。

    相关文章

      网友评论

          本文标题:Kotlin(run,apply)陷阱

          本文链接:https://www.haomeiwen.com/subject/lhlgmqtx.html