Kotlin艺术探索之扩展方法和属性代理

扩展方法

Kotlin支持扩展方法,扩展方法是个很有意思的东西

还是举个栗子比较直观

比如我们想打印10次“abc”的字符串,最容想到的是使用循环。那么单独抽出来成方法,就是这样

fun String.copyContent(times: Int): String{

    var string = StringBuilder()
    for (i in 0 until times){
        string.append(this)
    }
    return string.toString()
}

你仔细看看这个方法,它和普通方法有一点不太一样,那就是它的方法名前有一个 String.

这么写有什么好处呢?看下面的调用操作你就明白了

println( "abc".copyContent(10))

上面的结果就是输出10次abc的字符串

有没有发现很简洁,直接字符串点方法就ok了

通过上面方式定义的方法就是扩展方法,注意扩展方法的this代替的就是调用者“abc”

其实上面的栗子还可以写的更骚

怎么个骚操作呢,那就是使用运算符

operator fun String.times(times: Int): String{
    var string = StringBuilder()
    for (i in 0 until times){
        string.append(this)
    }
    return string.toString()
}

下面就是见证奇迹的时候了

 println("abc"*10)

不知道的一看会以为String类有这么一种运算呢,啊哈哈,可以说这波操作很骚了

属性代理

属性代理是什么,代理模式?

我们先看一个栗子:

Kotlin对常量进行延迟加载对时候就用到了属性代理,它是这样的:

val lazyValue: String by lazy {
    println("computed!")
    "Hello"
}

fun main() {
    println(lazyValue)
    println(lazyValue)
}

输出结果

computed!
Hello
Hello

可以看到computed!只输出了一次,这表明它的确是在用到这个常量的时候才去赋值。

该说回属性代理了,其实它的内部就是通过lazy这个属性代理实现的

但是它怎么通过属性代理实现延迟加载的呢?这里不说,因为不是重点,也不是我举这个栗子的目的,笔者是想让你们感受到属性代理的强大之处,它把所有的具体实现都交给了某个属性来做,对外部来说是透明的,这就非常舒服了。

下面说说我们怎么去实现属性代理?

还是举个栗子:

实现通过属性代理的方式对变量进行赋值和取值的操作(栗子很简单,关键看实现)

属性代理类Delegate

class Delegate{

    private var value: String ?= null

    operator fun getValue(thisRef: Any?, property: KProperty<*>): String{
        println("$thisRef, thank you for delegating '${property.name}' to me!")
        return value?: ""
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        this.value = value
        println("$value has been assigned to '${property.name}' in $thisRef.")
    }

}

可以看到代理类有两个方法,setValue()和getValue()

注意:如果是常量val的话,只需要实现getValue就可以;如果是变量var,那就需要实现setValue()和getValue()两个方法

通过属性代理实现功能

    var de = Delegate()
    var b: String by de
    b = "10"
    println(b)

输出结果

10 has been assigned to 'b' in null.
null, thank you for delegating 'b' to me!
10

根据输出结果可以看到整个过程是通过属性代理类Delegate实现的

这个栗子虽然简单,但透过表面看本质,我们只需要通过一个属性就可以实现功能,至于怎么实现的对我们来说是透明的。

转载于:https://www.jianshu.com/p/1f0be129c239

猜你喜欢

转载自blog.csdn.net/weixin_33859665/article/details/91303059