Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/221.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在Kotlin中传递多个lambda函数以处理成功/失败的最佳方法_Android_Kotlin - Fatal编程技术网

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

Android 在Kotlin中传递多个lambda函数以处理成功/失败的最佳方法,android,kotlin,Android,Kotlin,这里是Kotlin的新手,正在尝试学习使用高阶函数和传递lambda的最佳方法。我创建这个方法是为了调用API并返回从字符串创建的对象,或者在出现问题时返回失败 fun getDeviceStatus(onSuccess: (Device) -> Unit, onFailure: ((String) -> Unit)? = null) { FuelClient.get(DEVICE_URL, success = { respo

这里是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

您可以为kotlin中的每个变量附加一个名称。像这样更改代码

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

对于这种特定情况,当第二个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
或类似的名称


当第二个参数是可选的时,这是很好的,但在其他方面就不太好了,因为它不会强制用户实际提供一个失败处理程序。我认为这不是一个好主意,因为它太容易意外地忽略一个失败处理程序。强制用户提供一个更好,即使它恰好是一个空的。因此或者,在这种情况下,最好使用命名参数,即使没有强制要求实际命名它们。

你可以按照苏哈伊布的答案中的建议,或者也可以使用Kovenant library的承诺之类的东西,它特别有很好的处理成功/失败的方法。谢谢。似乎有多种方法可以处理这个问题,我不确定我最喜欢哪一个,但这是一个很好的开始。如果有人想对不同的处理方法进行更好的解释,我发现这篇文章特别有用:命名参数的问题是它不会强迫开发人员使用它们,这使事情变得模棱两可