рано возвращаться из диапазона канала - PullRequest
0 голосов
/ 21 ноября 2018

Возможно ли реализовать что-то похожее на yield из python в go?То есть мне нужна парадигма производитель / потребитель, в которой потребитель может игнорировать значения, произведенные производителем, в любое время без проявления утечки памяти.

В python у меня может быть производитель, который производит бесконечные значения, и клиент можетпотреблять столько, сколько они хотят.

def producer():
  i = 0
  while True:
     yield i
     i += 1

def consumer():
   for i in producer():
     if i == 2:
        return

Общий совет для этого заключается в том, чтобы производитель возвращал канал, который клиент использует в выражении range, и производитель может помещать свои значения в канал.,Это нормально, если клиент считывает все значения в канале, но если клиент рано прерывает управление из цикла range, канал производителя останется зависшим навсегда, используя память.

package main

func yield() chan int {
    out := make(chan int)
    go func(){
        out <- 1
        out <- 2
        close(out)
    }()
    return out
}

func test(){
    for _ = range yield() {
        // return
    }
}

func main(){
    for {
        test()
    }
}

Если return в test не закомментировано, этот код будет использовать память без ограничений, потому что канал, возвращаемый yield, имеет значение, которое ожидает чтения, и, очевидно, ни канал, ни процедура не могут быть безопасно собраны мусором.

Некоторые возможные решения (ни одно из которых мне не нравится):

  1. Измените out в yield на буферизованный канал с точным количеством пространства в качестве значенийэто будет произведено.В этом случае yield может быть

    func yield () chan int {out: = make (chan int, 2) out <- 1 out <- 2 close (out) return out} </p>

Но это неоптимально, потому что я вообще не знаю, сколько произведет yield предметов.Этот стиль похож на простой возврат массива.

Пусть метод yield использует тайм-аут для ввода значений в канал, а если тайм-аут достигнут, закройте канал раньше.Это делает предположения о времени выполнения клиента, что кажется плохой идеей.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...