扩展方法
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实现的
这个栗子虽然简单,但透过表面看本质,我们只需要通过一个属性就可以实现功能,至于怎么实现的对我们来说是透明的。
网友评论