Kotlin支持擴展方法,擴展方法是個頗有意思的東西bash
仍是舉個栗子比較直觀app
好比咱們想打印10次「abc」的字符串,最容想到的是使用循環。那麼單獨抽出來成方法,就是這樣ui
fun String.copyContent(times: Int): String{
var string = StringBuilder()
for (i in 0 until times){
string.append(this)
}
return string.toString()
}
複製代碼
你仔細看看這個方法,它和普通方法有一點不太同樣,那就是它的方法名前有一個 String.this
這麼寫有什麼好處呢?看下面的調用操做你就明白了spa
println( "abc".copyContent(10))
複製代碼
上面的結果就是輸出10次abc的字符串代理
有沒有發現很簡潔,直接字符串點方法就ok了code
經過上面方式定義的方法就是擴展方法,注意擴展方法的this代替的就是調用者「abc」字符串
其實上面的栗子還能夠寫的更騷get
怎麼個騷操做呢,那就是使用運算符string
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實現的
這個栗子雖然簡單,但透過表面看本質,咱們只須要經過一個屬性就能夠實現功能,至於怎麼實現的對咱們來講是透明的。