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實現的

這個栗子雖然簡單,但透過表面看本質,我們只需要通過一個屬性就可以實現功能,至於怎麼實現的對我們來說是透明的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章