如何在Kotlin中简化代码?

时间:2018-06-29 02:25:04

标签: android kotlin

代码A中有很多重复的代码,我希望简化代码,但是代码B不起作用,如何解决?谢谢!

代码A

aMDetail?.findByDeviceDef<BluetoothDef>()?.setDevice(mContext)
aMDetail?.findByDeviceDef<WiFiDef>()?.setDevice(mContext)
aMDetail?.findByDeviceDef<ScreenDef>()?.setDevice(mContext)

代码B

with(aMDetail?){
    findByDeviceDef<BluetoothDef>()?.setDevice(mContext)
    findByDeviceDef<WiFiDef>()?.setDevice(mContext)
    findByDeviceDef<ScreenDef>()?.setDevice(mContext)
}

2 个答案:

答案 0 :(得分:5)

修改

正如@ veritas1回答和@EpicPandaForce所评论的那样,可能有两种方法可以满足您的需求,但是每种方法在将参数传递给块以及返回值是什么方面都有一些差异,我写道一些代码来表明差异:

class Test {
    fun a() {}

    fun b() {}

    fun c() {}
}

fun main(args: Array<String>) {
    val test: Test? = Test()

    test?.apply {
        // `apply` passes the receiver as `this`
        a()
        b()
        c()
    }?.a() // works, because `apply` returns `this`

    test?.also {
        // `also` passes the receiver as `it`
        with(it) {
            a()
            b()
            c()
        }
    }?.a() // works, because `also` returns `this`

    test?.run {
        // `run` passes the receiver as `this`
        a()
        b()
        c()
    }?.a() // won't compile, because `run` returns the block's return value (Unit)

    test?.run {
        // `run` passes the receiver as `this`
        a()
        b()
        c()
        this
    }?.a() // works, because `run` returns the block returns `this`

    test?.let {
        with(it) {
            a()
            b()
            c()
        }
    }?.a() // won't compile, because `let` returns the block's return value (Unit)

    test?.let {
        with(it) {
            a()
            b()
            c()
        }
        it
    }?.a() // works, because the block returns `it`
}

Elye中的此决策树图可以帮助您选择最佳方法:

  

Decision

总而言之,run最适合您的情况,因为您需要null checks并发送this作为参数可以简化代码:

test?.run {
    // `run` passes the receiver as `this`
    a()
    b()
    c()
}

原始答案

尝试使用let

aMDetail?.let {
    with(it) {
        findByDeviceDef<BluetoothDef>()?.setDevice(mContext)
        findByDeviceDef<WiFiDef>()?.setDevice(mContext)
        findByDeviceDef<ScreenDef>()?.setDevice(mContext)
    }
}

答案 1 :(得分:4)

您可以使用apply。这将使aMDetail无效,然后在aMDetail的上下文中执行代码块。

aMDetail?.apply {
    findByDeviceDef<BluetoothDef>()?.setDevice(mContext)
    findByDeviceDef<WiFiDef>()?.setDevice(mContext)
    findByDeviceDef<ScreenDef>()?.setDevice(mContext)
}