Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

alternatively:

    var errClosed = errors.New("closed")

    func doAThing[T any](ctx context.Context, c chan T) (T, error) {
        // the generics are not necessary, but they're also not awful for
        // DRYing up this type of a select.
        select {
        case <-ctx.Done():
            var empty T
            return empty, fmt.Errorf("could not doAThing: %w", ctx.Err())
        case item, ok := <-c:
            if !ok {
                var empty T
                return empty, fmt.Errorf("channel of type %T is done: %w", empty, errClosed)
            }
            return item, nil
        }
    }

    // ... and later...
    for {
        item, err := doAThing(ctx, channel)
        if err != nil {
            break
        }
        // code goes here
    }
I dislike labeled loops, naked returns, and else statements, so this is the pattern I use.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: