共计 1660 个字符,预计需要花费 5 分钟才能阅读完成。
扩大函数
Kotlin 扩大函数可能对⼀个类扩大新性能⽽⽆需继承该类或者使⽤像装璜者这样的设计模式。利用他能够缩小很多代码,晋升咱们的开发效率。
扩大函数的申明
申明⼀个函数,而后让被扩大的类型作为函数的前缀就能够了,比方上面对 TextView 的扩大
fun TextView.setDrawableLeft(drawableId: Int?) {val drawable = ContextCompat.getDrawable(this.context, drawableId)
if (drawable == null) {
setCompoundDrawables(
null,
compoundDrawables[1],
compoundDrawables[2],
compoundDrawables[3]
)
} else {
drawable.apply {setBounds(0, 0, minimumWidth, minimumHeight)
setCompoundDrawables(
drawable,
compoundDrawables[1],
compoundDrawables[2],
compoundDrawables[3]
)
}
}
}
而后咱们就能够应用 TextView 的实例调用 setDrawableLeft() 办法。尽管看上去如同咱们为 TextView 新增了一个办法,然而其实扩大是动态的,他并没有为扩大类型中插入新的办法
那么他是如何实现的呢,咱们反编译以下 class 文件,查看对应的 java 文件就明确了
扩大函数原理
public static final void setDrawableLeft(@NotNull TextView $this$setDrawableLeft, @Nullable Integer drawableId)
{// 省略其余代码}
原来是给咱们生成了一个对应的 java 静态方法,第一个参数就是接受者类型的对象,所以在办法外部能够拜访这个类中的成员。
既然是生成了 java 代码,那么这个办法就能够被其余 java 代码拜访
TextViewKt.setDrawableLeft(textview,drawableId)
扩大属性
和扩大函数相似,这种扩大也是动态的,并没有给原来的类增加新的属性
扩大属性的申明
val StringBuilder.lastChar: String
get() {if (this.isEmpty()) {return ""}
return this.substring(length - 1)
}
申明形式和扩大函数也相似,须要一个接受者类型,在作用域类,this 就代表这个接受者对象,因为这里 lastChar 咱们定义的是 val,所以只用定义 get() 办法就能够了,如果是 var 类型,还须要定义 set() 办法,扩大字段的应用和失常字段一样。
val s = StringBuilder("value")
println(s.lastChar)
扩大属性原理
持续反编译查看对应的 java 源码
public static final String getLastChar(@NotNull StringBuilder $this$lastChar)
{Intrinsics.checkNotNullParameter($this$lastChar, "<this>");
if ((((CharSequence)$this$lastChar).length() == 0 ? 1 : 0) != 0) {return "";}
String str = $this$lastChar.substring($this$lastChar.length() - 1);Intrinsics.checkNotNullExpressionValue(str, "this.substring(length - 1)");return str;
}
能够看到其实也是生成了一个静态方法,java 代码调用如下
StringBuilder s = new StringBuilder("value");
String lastChar = EXTKt.getLastChar(s);
正文完