как объединить несколько срезов с помощью подпрограмм go - PullRequest
0 голосов
/ 22 мая 2018

Новый, чтобы пойти.Я пытаюсь прочитать map[int][]string, записать фрагмент строки в промежуточный канал, а затем, когда все будет записано, прочитать все строки из промежуточного канала в другой канал и, наконец, прочитать канал в другой маршрут.

Я не могу понять, какой хороший неблокирующий способ чтения из промежуточного канала.

package main

import (
    "fmt"
)

func f1(c chan []string, q chan int) {
  // intermediate channel
    ic := make(chan []string, 10)

  hmap := map[int][]string{
    0: []string{"a", "b", "c"},
    1: []string{"d", "e",},
    2: []string{"f", "g", "h"},
  }
  // for every elem in hmap put the values into intermediate channel
    for _, v := range hmap {
       f2(v, ic)
    }

  // everything is in intermediate channel by now
  // read all the []string and concatenate them into a slice in a
  // non-blocking fashion
  var strs []string
  for v := range ic {
    strs = append(strs, v...)
  }
    // strs := <-ic
  fmt.Println(strs)
    select {
  case c <- strs:
    fmt.Println("Received strings.")
  default:
    fmt.Println("did not receive anything.")
  }
    q <- 1
}

func f2(v []string, ic chan []string) {
    select {
    case ic <- v:
        fmt.Println("Sent to intermediate channel:", v)
    default:
        fmt.Println("nothing to send...")
    }
}
func f3(c chan []string) {
    fmt.Println(<-c)
}

func main() {
    c := make(chan []string, 10)
    q := make(chan int)
    go f1(c, q)
    go f3(c)
    fmt.Println(<-q) // to wait for the quit to be set
}

go run main.go для запуска.

Эта программа заходит в тупик.Как я могу избежать тупика?

1 Ответ

0 голосов
/ 22 мая 2018

Как сказал @zerkms в комментарии, вам нужно закрыть канал, когда вы закончите запись, или for v := range ic { заблокируется.

package main

import (
    "fmt"
)

func f1(c chan []string, q chan int) {
    ic := make(chan []string, 10)

    hmap := map[int][]string{
        0: []string{"a", "b", "c"},
        1: []string{"d", "e"},
        2: []string{"f", "g", "h"},
    }
    for _, v := range hmap {
        f2(v, ic)
    }
    // done writing strings, close the channel
    close(ic)
    var strs []string
    for v := range ic {
        strs = append(strs, v...)
    }
    fmt.Println(strs)
    select {
    case c <- strs:
        fmt.Println("Received strings.")
    default:
        fmt.Println("did not receive anything.")
    }
    q <- 1
}

func f2(v []string, ic chan []string) {
    select {
    case ic <- v:
        fmt.Println("Sent to intermediate channel:", v)
    default:
        fmt.Println("nothing to send...")
    }
}
func f3(c chan []string) {
    fmt.Println(<-c)
}

func main() {
    c := make(chan []string, 10)
    q := make(chan int)
    go f1(c, q)
    go f3(c)
    fmt.Println(<-q) // to wait for the quit to be set
}

https://play.golang.org/p/qZoAElTlkAa

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