kotlin1.5.0

密封类,密封接口

​ 密封类,密封接口就是一种专门用来配合when语句使用得到类,举个例子,假如在Android中我们有一个view,我们需要动态的设置他的显示和影藏,或者,动态设置他的偏移,可以这么做:

1
2
3
4
5
6
7
8
9
10
11
12
sealed class UiOP{
object Show:Uiop()
object Hide:Uiop()
class TranslateX(val px:Float):Uiop()
class TranslateY(val px:Float):UiOp()
}
fun execute(view:View,op:Uiop) = when(op){
UiOp.Show -> view.visibility = View.VISIBLE
UiOp.Hide -> view.visibility = View.GONE
is UiOp.TranslateX -> view.translationX = op.px // 这个 when 语句分支不仅告诉 view 要水平移动,还告诉 view 需要移动多少距离,这是枚举等 Java 传统思想不容易实现的
is UiOp.TranslateY -> view.translationY = op.px
}

takeIf and takeUnless

官方网址:Scope functions | Kotlin (kotlinlang.org)

takeIf:如果匹配为true那么就返回对象本身,否则返回null

takeUnless:如果不匹配就返回对象本身,否则返回null

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import kotlin.random.*
/**
* 当takeIf里面的表达式返回true 那么就返回自身 否则就返回null
* 当takeUnless里面的表达式返回false 那么就返回本身 否则返回null
*/
fun main() {
val number = Random.nextInt(100)

val evenOrNull = number.takeIf { it % 2 == 0 }
val oddOrNull = number.takeUnless { it % 2 == 0 }
println("even: $evenOrNull, odd: $oddOrNull")
}
// even: 76, odd: null
// even: null, odd: 29
// even: 12, odd: null

项目里面我第一使用的场景是,在使用kotlin的代理模式+DataBind的时候,我需要检测参数是否带有Bindable注解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
internal fun getBindingIdByProperty(property: KProperty<*>): Int {
val bindingProperty = property.takeIf {
// 检测是否带了注解
it.getter.hasAnnotation<Bindable>()
}
?: throw IllegalArgumentException("KProperty: ${property.name} must be annotated with the `@Bindable` annotation on the getter.")
//没带的话我直接抛出了个异常 demo见:PokexActivity
val propertyName = bindingProperty.name.decapitalize(Locale.ENGLISH)
val bindingPropertyName = propertyName
.takeIf { it.startsWith(JAVA_BEANS_BOOLEAN) }
?.replaceFirst(JAVA_BEANS_BOOLEAN, String())
?.decapitalize(Locale.ENGLISH) ?: propertyName
return bindingFieldsMap[bindingPropertyName] ?: BR._all
}