срез, канал пустого интерфейса в качестве аргумента функции - PullRequest
0 голосов
/ 19 июня 2020

Я хотел бы реализовать функцию распараллеливания, которая в отсутствие универсальных шаблонов выглядит так:

func Parallelize(s []interface{}, c chan interface{}, f func(interface{}, chan interface{})) {
    var wg sync.WaitGroup
    defer wg.Done()

    for _, si := range s {
        wg.Add(1)
        go f(si, c)
    }

    wg.Wait()
    close(c)
}

Я бы хотел разрешить передачу объектов любого типа, но чтобы первый Аргумент - это фрагмент объектов, второй - канал, а третий - функция, которая принимает объект и канал.

По-видимому, компилятору go аргументы не нравятся. Это не позволяет мне вызывать эту функцию так:

a := make([]*A)
c := make(chan *A)
f := func(_a *A, _c chan A) {
   ...
}
Parallelize(a, c, f)

Как правильно поступить?

1 Ответ

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

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

Один из способов сделать это - понять, что вам действительно не нужно передавать элементы среза:

func Parallelize(n int, c chan interface{}, f func(int, chan interface{})) {
    var wg sync.WaitGroup
    defer wg.Done()

    for i:=0;i<n;i++ {
        wg.Add(1)
        go f(i, c)
    }

    wg.Wait()
    close(c)
}

И вызвать его, используя:

Parallelize(len(slice), ch, func(i int,ch chan interface{}) {
   // use slice[i]
})

Вам также не нужно передавать канал:

func Parallelize(n int, f func(int)) {
    var wg sync.WaitGroup
    defer wg.Done()

    for i:=0;i<n;i++ {
        wg.Add(1)
        go f(i)
    }

    wg.Wait()
}

И назовите его:

Parallelize(len(slice), func(i int) {
   // use slice[i] and chan ch
})`
close(ch)

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

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