Kotlin的扩展函数
Kotlin的扩展函数,在日常Android开发中经常用到,当然前提你使用Kotlin来开发,之前有次和同事聊天我说完这句话,他说:他都不用这些,因为他只用Java开发。我:emmm.. 对~!你说得对。 举几个我们常见的,已经写好了给我们直接用的:
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(this)
}
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block(this)
return this
}
public inline fun String.filter(predicate: (Char) -> Boolean): String {
return filterTo(StringBuilder(), predicate).toString()
}
有了官方给我们的这些那么好用的扩展函数,的确能很好地减少我们的代码量,如下:
val stringTo20 = "20"
Log.e(TAG, "value:${stringTo20.toInt()}")
E/MainActivity: value:20
点击这个toInt() 方法,进去看看就是经常用到的字符串转数字方法
@kotlin.internal.InlineOnly
public actual inline fun String.toInt(): Int = java.lang.Integer.parseInt(this)
但是如果我们写成这样呢?Crash是必然的了
val stringTo20 = "www"
Log.e(TAG, "value:${stringTo20.toInt()}")
java.lang.NumberFormatException: For input string: "www"
当然,如果那个字符串是正常的数字字符串,那我们的代码的确直接用toInt(),但是,凡事都有例外,假如有个需求是你要从后台获取一个“数字”字符串,不要问我问什么不直接用json,我举例子而已,然后突然某天配置错了然后配了个不是纯数字的,
而你又忘了try catch 直接 toInt(),不要问我为什么网络请求不处理这种异常,我举例子而已。
开发(不知道配置错了):呃,你手机中毒了?怎么App闪退了。
那我们平时开发是不是应该尽力去避免这种情况呢?
val stringTo20 = "www"
fun String.forceToInt(default: Int = 0) : Int {
return if(this.filter { it.isDigit() }.any { this.isNotEmpty() }){
toInt()
}else{
default
}
}
Log.e(TAG, "value:${stringTo20.forceToInt(-1)}")
我们可以利用扩展函数处理这种情况,简单又方便。
Kotlin的infix函数
这个infix符号修饰的是中缀函数,我们多用于修饰扩展函数,记得有且只有一个参数
举应用MutableLiveData作为例子
infix fun <T:Any> MutableLiveData<T>?.post(newValue:T){
this?.postValue(newValue)
}
infix fun <T:Any> MutableLiveData<T>?.set(newValue:T){
this?.value = newValue
}
//可以直接使用变成
(MutableLiveData) data post newValue
(MutableLiveData) data set newValue
这种方法并不会带来什么性能上的优化,代码相比 .执行方法显得直观,特别是用于数字计算或者合并某些内容等等,切勿乱起名字,否则会很难拿维护,尽量保证名字能和功能相关
如下:
button translationX 200f
infix fun View.translationX(float: Float){
translationX = float
}
//如果像这样,很难有第一反应是translationX,我会以为是view.x = float
button toX 200f
infix fun View.toX(float: Float){
translationX = float
}
未完,后续更新