logoalt Hacker News

jitllast Wednesday at 1:04 AM0 repliesview on HN

Moving every success value to the heap seems like a big loss to me but I don't see an alternative. I think going the interface route also ends up wrapping everything in an even fatter pointer. But at least I get to think "ah maybe this isn't going to get boxed and it will be free".

    interface Result[T] {
     IsOk(): bool
     IsErr(): bool
     Unwrap(): T
     UnwrapError(): error
    }
    
    // Ok is a Result that represents a successful operation.
    struct Ok[T] {
     Value: T
    }
    
    func Ok[T](value T) Result[T] {
     return Ok[T]{Value: value}
    }
    
    func (s Ok[T]) IsOk() bool {
     return true
    }
    
    func (s Ok[T]) IsErr() bool {
     return false
    }
    
    func (s Ok[T]) Unwrap() T {
     return s.Value
    }
    
    func (s Ok[T]) UnwrapError() error {
     panic("UnwrapError called on Ok")
    }
    
    
    // Err is a Result that represents a failed operation.
    struct Err[T] {
     Reason: error
    }
    
    func Err[T](reason error) Result[T] {
     return Err[T]{Reason: reason}
    }
    
    func (e Err[T]) Error() string {
     return e.Reason.Error()
    }
    
    func (e Err[T]) IsOk() bool {
     return false
    }
    
    func (e Err[T]) IsErr() bool {
     return true
    }
    
    func (e Err[T]) Unwrap() T {
     panic(fmt.Errorf("Unwrap called on Err: %w", e.Reason))
    }
    
    func (e Err[T]) UnwrapError() error {
     return e.Reason
    }