kotlin一些比较酷的特性

原文在 https://github.com/Zhuinden/guide-to-kotlin

lambda types, tailing lambdas

class MyAdapter(
    private var items: List,
    private val clickListener: (Item) -> Unit
): RecyclerView.Adapter() {
    ....
}
val adapter = MyAdapter(items) { item ->
    doSomethingWith(item)
}

//如果有多个lambdas, 那么最好是用参数名称区分一下
createDialog(title, description,
    onPositiveClick = { yay() },
    onNegativeClick = { nay() }
)

someView.setOnClickListener { view -> // if unnamed, it is called `it`
    // ...
}

//没有使用的参数 可以使用_
someView.waitForMeasure { _, _, _ -> 
    // unused parameters can be named as `_`
}

如果需要return, 则使用return@[caller], for example return@onClick.

方法引用

fun acceptsLambda(lambda: () -> Unit) {
    if(...) {
        lambda() // same as `lambda.invoke()`
    }
}

fun doSomething() {
}

fun execute() {
    acceptsLambda(::doSomething)
}

typealias

typealias ItemClickListener = (Item) -> Unit

class MyAdapter(
    private var items: List,
    private val clickListener: ItemClickListener
): RecyclerView.Adapter() {
    ....
}

lambdas with receivers

inline fun Realm.runTransaction(crossinline transaction: Realm.() -> Unit) {
    val realm = this
    realm.executeTransaction {
        transaction(realm)
    }
}

realm.runTransaction {
    insertOrUpdate(Dog("Hello"))
    insertOrUpdate(Cat("World"))
}

拓展函数,拓展属性

fun View.show() {
    this.visibility = View.VISIBLE
}

fun View.hide() {
    this.visibility = View.GONE
}

// myView.visibility = View.VISIBLE
myView.show()

var View.isVisible: Boolean
    get() = this.visibility == View.VISIBLE
    set(value) {
        if (value) {
            show()
        } else {
            hide()
        }
    }

inline fun Array.forEachNonDemo(action: (Account) -> Unit) {
    this.filter { !it.isDemo() }.forEach(action)
}

fun View.objectAnimate() = ViewPropertyObjectAnimator.animate(this)

fun View.animateFadeOut(duration: Long = 325, hideOnFinish: Boolean = true): Animator = run {
    alpha = 1f
    objectAnimate()
        .alpha(0f)
        .setDuration(duration)
        .get()
        .apply {
            if (hideOnFinish) {
                onFinish {
                    hide()
                }
            }
        }
}

fun View.animateFadeIn(duration: Long = 325, showOnStart: Boolean = true): Animator = run {
    alpha = 0f
    objectAnimate()
        .alpha(1f)
        .setDuration(duration)
        .get()
        .apply {
            if (showOnStart) {
                onStart {
                    show()
                }
            }
        }
}

标准库里的函数— apply, let, alse, run, with

fun okHttpClient() = OkHttpClient.Builder().apply {
    setInterceptor(NetworkInterceptor())
    baseUrl(BuildConfig.BASE_URL)
}.build()

fragment.arguments = Bundle().also { bundle -> 
    bundle.putString("hello", "hello")
}

let和run: let可以让我们执行一个代码块,然后返回一个新的类型,而run执行一个代码块之后,返回this

val domainObject = dao.findFirst().let { DomainObject(it) }

fun someFunction() {
    val someValue = "beep" // some local variable you cannot avoid, or scoping functions would make hard to read
    return result
}
//等同于
fun someFunction() = run {
    val someValue = "beep"
    result
}

with 减少冗余代码使用次数

with(recyclerView) {
    adapter = MyAdapter()
    layoutManager = LinearLayoutManager(this@MyActivity) 
}

takeIf,takeUnless

Integer someNumber = bundle.getInt("someNumber", -1);
if(someNumber == -1) {
   someNumber = null;
}

val someNumber = bundle.getInt("someNumber", -1).takeIf { it >= 0 }

val someText = bundle.getInt("someNumber", -1).takeIf { it >= 0 }?.let { "$it" }

val someText = bundle.getInt("someNumber", -1).takeIf { it >= 0 }?.let { "$it" } ?: ""

val someText = something.takeIf { condition } ?: throw IllegalArgumentException("$something is invalid")

inline functions(crossinline, noinline)

集合

inline fun

val query = realm.where(MyObject::class.java)

val query = realm.where()

sealed classes

sealed class Message {
    data class TextMessage(val text: String): Message()
    data class PictureMessage(val image: ByteArray): Message()
}

val message = ...
when(message) {
    is TextMessage -> println("${message.text}")
    is PictureMessage -> sendToFriends(message.image)
}

infix keyword

tuples

你可能感兴趣的:(kotlin一些比较酷的特性)