편집 : 페어 환원 예 코드 및 응답의 재정렬 부를 첨가.
선호하는 솔루션은 "채널 구조가 없도록 재구성"입니다. 구조 조정은 종종 여러 goroutine이 단일 채널로 보낼 수있는 기능을 사용할 수 있습니다. 따라서 각 소스를 개별 채널로 보내고 여러 채널에서 수신하는 대신 하나의 채널을 만들고 모든 소스에서 해당 채널을 보내도록하십시오.
이동은 채널 조각에서 수신하는 기능을 제공하지 않습니다. 그것은 자주 묻는 질문이며, 방금 주어진 해결책이 선호되는 반면, 그것을 프로그램하는 방법이 있습니다. 당신이 원래의 질문에서 "슬라이스 쌍을 줄이는 것"이라고 말하는 것으로 생각한 해결책은 이진 나누기와 정복 해결책입니다. 두 개의 채널을 하나로 멀티플렉싱하는 솔루션을 사용하는 한 잘 작동합니다. 이에 대한 예제 코드는 작업에 매우 가깝습니다.
예제 코드를 작동시키기위한 간단한 방법이 하나 빠져 있습니다. n을 감소시킬 때 채널 변수를 nil로 설정하는 행을 추가하십시오. 예를 들어, 코드를 읽게했습니다.
case v, ok := <-cin1:
if ok {
cout <- v
} else {
n--
cin1 = nil
}
case v, ok := <-cin2:
if ok {
cout <- v
} else {
n--
cin2 = nil
}
}
이 솔루션은 원하는 것을 처리하고 대기 상태가되지 않습니다. 그럼
, 조각을 다중화하는 기능으로이 솔루션을 포함하는 전체 예제 :
package main
import (
"fmt"
"time"
)
func multiplex(cin []chan int, cout chan int) {
var cin0, cin1 chan int
switch len(cin) {
case 2:
cin1 = cin[1]
fallthrough
case 1:
cin0 = cin[0]
case 0:
default:
cin0 = make(chan int)
cin1 = make(chan int)
half := len(cin)/2
go multiplex(cin[:half], cin0)
go multiplex(cin[half:], cin1)
}
for cin0 != nil || cin1 != nil {
select {
case v, ok := <-cin0:
if ok {
cout <- v
} else {
cin0 = nil
}
case v, ok := <-cin1:
if ok {
cout <- v
} else {
cin1 = nil
}
}
}
close(cout)
}
func main() {
cin := []chan int{
make(chan int),
make(chan int),
make(chan int),
}
cout := make(chan int)
for i, c := range cin {
go func(x int, cx chan int) {
for i := 1; i <= 3; i++ {
time.Sleep(100 * time.Millisecond)
cx <- x*10 + i
}
close(cx)
}(i, c)
}
go multiplex(cin, cout)
for {
select {
case v, ok := <-cout:
if ok {
fmt.Println("main gets", v)
} else {
return
}
}
}
}
아, 아주 좋은 해결책, 명확하고 간결. 고맙습니다! – elpres
여러 goroutine 대신 리플렉션을 사용하여 문제를 해결하는 기능 (https://godoc.org/github.com/eapache/channels#Multiplex)이 포함 된 패키지가 있습니다. – Evan