如何在kotlin中简化代码?

Hel*_*oCW 1 android kotlin

代码A中有许多重复的代码,我希望简单地说,但代码B不起作用,我该如何解决?谢谢!

代码A.

aMDetail?.findByDeviceDef<BluetoothDef>()?.setDevice(mContext)
aMDetail?.findByDeviceDef<WiFiDef>()?.setDevice(mContext)
aMDetail?.findByDeviceDef<ScreenDef>()?.setDevice(mContext)
Run Code Online (Sandbox Code Playgroud)

代码B.

with(aMDetail?){
    findByDeviceDef<BluetoothDef>()?.setDevice(mContext)
    findByDeviceDef<WiFiDef>()?.setDevice(mContext)
    findByDeviceDef<ScreenDef>()?.setDevice(mContext)
}
Run Code Online (Sandbox Code Playgroud)

Hon*_*uan 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`
}
Run Code Online (Sandbox Code Playgroud)

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

决策

总而言之,run最适合你的情况,因为你需要null checks和发送this作为参数可以使你的代码更简单:

test?.run {
    // `run` passes the receiver as `this`
    a()
    b()
    c()
}
Run Code Online (Sandbox Code Playgroud)

原始答案

试试let:

aMDetail?.let {
    with(it) {
        findByDeviceDef<BluetoothDef>()?.setDevice(mContext)
        findByDeviceDef<WiFiDef>()?.setDevice(mContext)
        findByDeviceDef<ScreenDef>()?.setDevice(mContext)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么不只是`?.run {`? (2认同)