擴(kuò)展函數(shù)與屬性
在Java中獲取String中的第一個(gè)字符责蝠,StringUtil.firstChar(str)
可能是這樣寫的守问,但是要想`"ABC".firstChar()是不可能的,因?yàn)镴ava中String是final類蚁飒,在Kotlin中就不一樣了榛鼎。
1. 擴(kuò)展函數(shù)
給String類中添加firstChar方法
fun String.firstChar(): String {
if (this.length == 0) return ""
else return this[0].toString()
}
fun main() {
println("123".firstChar()) // 1
}
給List添加一個(gè)filter方法
fun <T> List<T>.Myfilter(f: (T) -> Boolean): List<T> {
val result = ArrayList<T>().apply {
this@Myfilter.forEach {
if (f(it)) add(it)
}
}
return result
}
fun main() {
val list = listOf<Int>(1, 2, 3, 4)
println(list.Myfilter { it % 2 == 0 })
}
2. 擴(kuò)展屬性
var <T> MutableList<T>.firstElement: T
get() {
return this[0]
}
set(value) {
this.set(0, value)
}
fun main() {
val list = listOf<Int>(1, 2, 3, 4)
println((list as MutableList).firstElement)
}
3. 擴(kuò)展的實(shí)現(xiàn)
把代碼反編譯成java代碼乞封,可以發(fā)現(xiàn)鲫惶,拓展方法和屬性都是被翻譯成了靜態(tài)的方法
public final class ImplementFunKt {
@NotNull
public static final String firstChar(@NotNull String $this$firstChar) {
Intrinsics.checkParameterIsNotNull($this$firstChar, "$this$firstChar");
return $this$firstChar.length() == 0 ?"":String.valueOf($this$firstChar.charAt(0));
}
public static final Object getFirstElement(@NotNull List $this$firstElement) {
Intrinsics.checkParameterIsNotNull($this$firstElement, "$this$firstElement");
return $this$firstElement.get(0);
}
public static final void setFirstElement(@NotNull List $this$firstElement, Object value) {
Intrinsics.checkParameterIsNotNull($this$firstElement, "$this$firstElement");
$this$firstElement.set(0, value);
}
}
4.this沖突
如前面的filter函數(shù)中出現(xiàn)this沖突,
fun <T> List<T>.Myfilter(f: (T) -> Boolean): List<T> {
val result = ArrayList<T>().apply {
this@Myfilter.forEach {
if (f(it)) add(it)
}
}
return result
}
this會(huì)默認(rèn)指向最內(nèi)層對象实抡,this@Myfilter就是使用限定符解決this指針沖突的問題