在Kotlin中传递多个lambda函数以处理成功/失败的最佳方式

qhhrdooz  于 2023-02-16  发布在  Kotlin
关注(0)|答案(3)|浏览(117)

我是Kotlin的新手,正在学习使用高阶函数和传递lambda的最佳方法。我创建了这个方法来调用API,并返回从字符串创建的对象,或者在出错时返回失败。

fun getDeviceStatus(onSuccess: (Device) -> Unit, onFailure: ((String) -> Unit)? = null) {

        FuelClient.get(DEVICE_URL,
                success = { responseString ->

                    val adapter = MoshiUtil.moshi.adapter(Device::class.java)

                    val deivce= adapter.fromJson(responseString)!!

                    onSuccess(device)
                },
                failure = { onFailure?.invoke(it.message!!)})

    }

我可以像这样很好地使用这个函数:

DeviceService.getDeviceStatus(
                { w ->
                    print("device")
                },
                { e -> print(e) })

但是让我有点困扰的是,我不能看到函数的名称来了解每个函数的功能。我想知道是否有更干净/更好的方法来做到这一点,比如

DeviceService.getDeviceStatus(){
            onSuccess{print("device")}
            onFailure{print("error")}
        }

或许

DeviceService.getDeviceStatus()
                .onSuccess{print("device")}
                .onFailure{print("error")}

但是这些都给出了错误。关于如何最好地处理非常常见的onSuccess/onFailure用例,有什么想法吗?Thx

3ks5zfa0

3ks5zfa01#

你可以在Kotlin中给每个变量附加一个名字。

DeviceService.getDeviceStatus(
                onSuccess = { w ->
                    print("device")
                },
                onFailure = { e -> print(e) })
46qrfjad

46qrfjad2#

对于这种特定情况,当第二个lambda是可选的时,infix函数工作得非常好:

sealed class DeviceStatusResult {
    abstract infix fun onFailure(handler: (String) -> Unit)
}

class DeviceStatusSuccess(val device: Device) : DeviceStatusResult() {
    override fun onFailure(handler: (String) -> Unit) = Unit
}

class DeviceStatusFailure(val errorMessage: String) : DeviceStatusResult() {
    override fun onFailure(handler: (String) -> Unit) = handler(errorMessage)
}

fun getDeviceStatus(onSuccess: (Device) -> Unit): DeviceStatusResult {
    // get device status
    // if (success)
    val device = Device()
    onSuccess(device)
    return DeviceStatusSuccess(device)
    // else
    // return DeviceStatusFailure(message)
}

那么它可以像

getDeviceStatus { device ->
    println(device)
} onFailure { errorMessage ->
    System.err.println(errorMessage)
}

也许onFailure应该被称为orFail或类似的东西。
当第二个参数是可选的时候是很好的,但不是很好,因为它不强迫用户提供一个失败处理程序。而且我不认为这是一个好主意,因为它太容易意外地忽略一个失败处理程序。强迫用户提供一个失败处理程序要好得多,即使它碰巧是一个空的。因此,在这种情况下最好使用命名参数。尽管没有人强迫我们给它们命名。

nwlls2ji

nwlls2ji3#

例如,我们有一个类,它需要有一个以上的函数,如两个函数作为参数:

class TestClass internal constructor(
  private val onClickShowName: (String) -> Unit,
  private val onClickShowSurname: (String) -> Unit
) { //Your work. }

然后你需要创建瓦尔作为TestClass:

class MainActivity {
    val mTestClass = TestClass(
        onClickShowName = {dataText: String -> Log.i("TEST", dataText)},
        onClickShowSurname = {dataText: String -> Log.i("TEST", dataText)}
    )
}

相关问题