bpr*_*r10 5 generics functional-programming higher-order-functions kotlin
我有一组具有不同签名和参数的函数,但它们都可能抛出异常。我不想在每个函数中添加 try-catch,而是想编写一个内联函数,该函数将函数作为参数并在 try-catch 块中调用此函数,并返回包装异常的某些类型。
// first function.
fun foo() -> String
// second function.
fun bar(argument: String) -> Boolean
// Result Type
sealed class Result<out R> {
data class Success<out T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
}
// Wrapper Function
inline fun <T, R> safeCall(call: (T) -> R): Result<R>
// This Returns Result<String>
safeCall {
foo()
}
// This Returns Result<Boolean>
safeCall {
bar()
}
Run Code Online (Sandbox Code Playgroud)
我在实施该方法时遇到问题safeCall()
。理想情况下,我希望它适用于任何底层功能。我可以让它工作,foo()
或者bar(argument: String)
但不能两者兼而有之。
inline fun <T, R> safeCall(
call: (T) -> R, // This syntax forces to to have only one parameter.
): Result<R> {
return try {
val result: R = call() // This throws compilation error.
Result.Success(result)
} catch (e: Exception) {
Result.Error(e)
}
}
Run Code Online (Sandbox Code Playgroud)
PS - Kotlin 和函数式编程相当陌生。
当然!这听起来是一个合理的设计模式。只是一些注释。
inline fun <T, R> safeCall(call: (T) -> R): Result<R>
Run Code Online (Sandbox Code Playgroud)
safeCall
的论证本身不应该需要论证。这只是我们要调用的代码块,因此这将是一个更合适的签名。
inline fun <R> safeCall(call: () -> R): Result<R>
Run Code Online (Sandbox Code Playgroud)
至于如何实际实施,听起来你的想法都是正确的。只需尝试在实际的 Kotlin 块内调用该函数即可try
。
inline fun <R> safeCall(call: () -> R): Result<R> {
try {
return Result.Success(call())
} catch (e: Exception) {
return Result.Error(e)
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以将其称为
safeCall {
foo()
}
safeCall {
bar("Example Argument")
}
Run Code Online (Sandbox Code Playgroud)
请记住,这bar
需要争论。即使该参数是在safeCall
范围之外定义的,它仍然可以通过闭包的魔力起作用。
val x = "This works :)"
safeCall {
bar(x)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2276 次 |
最近记录: |