Отключить стандартную часть оператора select - PullRequest
1 голос
/ 16 июня 2020

Мне нужен способ выполнить обработку в части оператора select по умолчанию, но затем отключить значение по умолчанию позже.

Я использовал оператор if, как в приведенном ниже коде, но после того, как завершение становится истинным, мы просто иметь занятый l oop, который (когда каналы пусты) просто продолжал бы вращать, проверяя завершенный флаг, который всегда будет истинным. Это не кажется правильным способом Go.

for {
    select {
    case p := <-subscriber.Next:
        ...
    case err := <subsriber.OnError:
        ...
    default:
        if !finished {
            subscriber.Subscribe(name, params)
            ...
            if ... { finished = true }
        }
        
    }
}

Я знаю, что вы не можете отключить часть по умолчанию, но должен быть лучший способ сделать это.

Ответы [ 2 ]

1 голос
/ 16 июня 2020

Мне не известно о чем-либо встроенном для этого, но вы можете ввести два разных оператора select в зависимости от вашего состояния.

for {
    // Without default case, wait only for cases
    if finished {
        select {
        case p := <-subscriber.Next:
            //...
        case err := <-subsriber.OnError:
            //...
        }
    } else {
        // Allow default case
        select {
        case p := <-subscriber.Next:
            //...
        case err := <-subsriber.OnError:
            //...
        default:
            subscriber.Subscribe(name, params)
        }
    }
}

Это, конечно, приведет к дублированию кода, но при по крайней мере, он не входит в l oop только для того, чтобы узнать, что ничего не нужно делать.

1 голос
/ 16 июня 2020

Вы не можете отключить предложение default, но можете отключить предложение case, присвоив каналу nil. Возможно, создайте очень быстрый тикер, как в приведенном ниже коде. Приведенный ниже код назначает канал C из тикера на defaultCh, а затем отключает его, назначив nil.

    ticker := time.NewTicker(time.Microsecond)
    defaultCh := ticker.C
    for {
        select {
            case p := <-subscriber.Next:
                ...
            case err := <subscriber.OnError:
                ...
            case <-defaultCh:
                subscriber.Subscribe(name, params)
                ...
                if finished {
                    defaultCh = nil
                    ticker.Stop()
                }
            }
        }
    }
...