Swift имеет тип Result, который объявлен следующим образом.
enum Result<Success, Failure: Error> {
case success(Success)
case failure(Failure)
}
Что можно использовать так:
enum FooError: Error {
case fizzReason
case barReason
case bazReason
}
func returnResult() -> Result<String, FooError> {
// ... Just imagine this method returns an error
}
switch returnResult() {
case .success(let string):
print(s)
case .failure(.fizzReason):
// do something
case .failure(.barReason):
// do something
case .failure(.bazReason):
// do something
}
Есть ли в Kotlin аналогичный тип данных, который можно использовать таким же образом?





Я не знаю, есть ли что-то подобное в Kotlin, но вот реализация, которая должна делать то же самое:
sealed class Result<out Success, out Failure>
data class Success<out Success>(val value: Success) : Result<Success, Nothing>()
data class Failure<out Failure>(val reason: Failure) : Result<Nothing, Failure>()
Фактический пример:
fun echoString(string : String) : Result<String, Exception> {
return if (string.isEmpty()) {
Failure(Exception("Error"))
} else {
Success(string)
}
}
fun main(args : Array<String>) {
when(val result = echoString("string")) {
is Success -> println(result.value)
is Failure -> println(result.reason)
}
}
Kotlin имеет Результат с такими свойствами, как isFailure и успех, которые в основном эквивалентны результату Swift.
Резюме
Result, a type in the Kotlin standard library that is effectively a discriminated union between successful and failed outcome of execution of Kotlin function — Success T | Failure Throwable, where Success T represents a successful result of some type T and Failure Throwable represents a failure with any Throwable exception. For the purpose of efficiency, we would model it as a generic inline class Result in the standard library.
Result нельзя использовать в качестве прямого типа результата функций Kotlin, свойства типа Result также ограничены: например.
fun findUserByName(name: String): Result<User> // ERROR: 'kotlin.Result' cannot be used as a return type
fun foo(): Result<List<Int>> // ERROR
fun foo(): Result<Int>? // ERROR
var foo: Result<Int> // ERROR
Однако разрешены функции, которые используют тип Result в универсальных контейнерах или получают результат в качестве типа параметра:
fun findIntResults(): List<Result<Int>> // Ok
fun receiveIntResult(result: Result<Int>) // Ok
Использование (запуск онлайн):
class NumberNotEvenException(var number: Int) : Exception("$number not even")
fun checkEvenNumbers(list: List<Int>): List<Result<Int>>{
var returnList = mutableListOf<Result<Int>>()
for (number in list){
if (number%2==0){
returnList.add(Result.success(number))
}else{
returnList.add(Result.failure(NumberNotEvenException(number)))
}
}
return returnList
}
fun checkResult(result: Result<Int>){
result.fold(onSuccess = { number ->
println("$number is even")
},onFailure = {
if (it is NumberNotEvenException){
println("${it.number} is Odd")
}
})
}
fun main() {
checkEvenNumbers((0..100).toList()).map {
checkResult(it)
}
}
Было бы лучше, если бы цитаты с важной информацией из всех ссылок были добавлены непосредственно в вопрос. Поскольку гиперссылки имеют тенденцию ломаться, а связанная информация может измениться.
Тип результата в стандартной библиотеке имеет очень мало практического применения, потому что он существует для решения конкретной проблемы и не может использоваться в общем — см. здесь: github.com/Kotlin/KEEP/blob/master/proposals/stdlib/…
Начиная с Kotlin 1.5 эти ограничения сняты, и вы можете свободно использовать монаду Kotlin Result в своем коде, нет необходимости создавать свой запечатанный класс.
Существует несколько реализаций, но две, о которых я знаю (и которые, как я знаю, активно поддерживаются):
Здесь: kotlinlang.org/api/latest/jvm/stdlib/kotlin/-результат