Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Migration Guide
Ok
/Err
as TypesThe migration to an inline value class means that using
Ok
/Err
as types is no longer valid.Consumers that need to introspect the type of
Result
should instead useResult.isOk
/Result.isErr
booleans. This naming scheme matches Rust'sis_ok
&is_err
functions.Before:
After:
Type Casting
When changing the return type to another result, e.g. the
map
function which goes fromResult<V, E>
toResult<U, E>
, consumers are encouraged to use theasOk
/asErr
extension functions in conjunction with theisOk
/isErr
guard.The example below calls
asErr
which unsafely casts theResult<V, E
toResult<Nothing, E>
, which is acceptable given theisOk
check, which satisfies theResult<U, E>
return type.The
asOk
/asOk
functions should not be used outside of a manual type guard viaisOk
/isErr
- the cast is unsafe.Removal of Deprecations
The following previously deprecated behaviours have been removed in v2.
binding
&SuspendableResultBinding
, usecoroutineBinding
insteadand
without lambda argument, useandThen
insteadResultBinding
, useBindingScope
insteadgetOr
without lambda argument, usegetOrElse
insteadgetErrorOr
without lambda argument, usegetErrorOrElse
insteadgetAll
, usefilterValues
insteadgetAllErrors
, usefilterErrors
insteador
without lambda argument, useorElse
insteadResult.of
, userunCatching
insteadexpect
with non-lazy evaluation ofmessage
expectError
with non-lazy evaluation ofmessage
Inline Value Class - Before & After
The base
Result
class is now modelled as an inline value class. References toOk<V>
/Err<E>
as types should be replaced withResult<V, Nothing>
andResult<Nothing, E>
respectively.Calls to
Ok
andErr
still function, but they no longer create a new instance of theOk
/Err
objects - instead these are top-level functions that return a type ofResult
. This change achieves code that produces zero object allocations when on the "happy path", i.e. anything that returns anOk(value)
. Previously, every successful operation wrapped its returned value in anew Ok(value)
object.The
Err(error)
function still allocates a new object each call by internally wrapping the providederror
with a new instance of aFailure
object. ThisFailure
class is an internal implementation detail and not exposed to consumers. As a call toErr
is usually a terminal state, occurring at the end of a chain, the allocation of a new object is unlikely to cause a lot of GC pressure unless a function that produces anErr
is called in a tight loop.Below is a comparison of the bytecode decompiled to Java produced before and after this change. The total number of possible object allocations is reduced from 4 to 1, with 0 occurring on the happy path and 1 occurring on the unhappy path.
Before: 4 object allocations, 3 on happy path & 1 on unhappy path
After: 1 object allocation, 0 on happy path & 1 on unhappy path