【问题标题】:Passing pointer through channel in Go Lang在 Go Lang 中通过通道传递指针
【发布时间】:2014-01-17 20:26:51
【问题描述】:

可以在 go lang 中通过通道传递指针吗?我需要传递结构,对其进行更改并在传递结构的同一函数中进行这些更改?

我试过了

chan <- &data

我得到了

# command-line-arguments .\o.go:130: cannot use &duom[i] (type *KaVartoti) as type KaVartoti in send

之后我尝试了

chan <- *data

我得到了

# command-line-arguments .\o.go:130: invalid indirect of duom[i] (type KaVartoti)

那么,Go ir 中是否可以通过 channel 发送指针?

【问题讨论】:

    标签: pointers go channel lang


    【解决方案1】:

    当然可以,例如

    package main
    
    type Data struct {
        i int
    }
    
    func func1(c chan *Data ) {
        for {
            var t *Data;
            t = <-c //receive
            t.i += 10 //increment
            c <- t   //send it back
        }
    }
    
    func main() {
        c := make(chan *Data)
        t := Data{10}
        go func1(c)
        println(t.i)
        c <- &t //send a pointer to our t
        i := <-c //receive the result
        println(i.i)
        println(t.i)
    }
    

    Go Playground

    您收到的错误告诉您,您的频道采用 KaVartoti 结构,您必须创建一个 KaVartoti 指针频道(chan *KaVartoti)。

    猜测一下,您的duom 变量是一个数组/切片,因此如果您想发送指向其中一个元素的指针,您可以使用&amp;duom[i] 的第一种方法

    【讨论】:

    • 曾经应该小心,尽管在同一个通道上发送和接收,以相同的方法,尤其是在像这里这样的goroutine 中运行时,会使该通道成为 1 路进,1 路出路。 IOW,不要通过迭代并将多个值发送到通道来同时尝试此操作:您不会以相同的顺序取回这些值。但是,如果这是您的用例,通过阻塞每个接收,就像这里主要做的那样,就可以了。
    【解决方案2】:

    检查以下示例:

    package main
    
    type weburl struct {
        url string
    }
    type responseweburl struct {
        contents, index string
    }
    
    
    var urlmap = make(map[string]weburl)
    func callurl(ch chan *responseweburl, index, url string, wg *sync.WaitGroup) {
        defer wg.Done()
        response, err := http.Get(url)
        if err != nil {
            fmt.Printf("%s", err)
            os.Exit(1)
        } else {
            defer response.Body.Close()
            contents, err := ioutil.ReadAll(response.Body)
            if err != nil {
                fmt.Printf("%s", err)
                os.Exit(1)
            }
            var responsedata = responseweburl{string(contents), string(index)}
            ch <- responsedata
        }
    
    }
    func main(){
        urlmap["google"] = weburl{"http://www.google.com"}
        urlmap["facebook"] = weburl{"http://www.facebook.com"}
        urlmap["linkedin"] = weburl{"http://www.linkedin.com"}
        ch := make(chan *responseweburl)
        for index, _ := range urlmap {
            fmt.Println("call url " + index)
            go callurl(ch, index, urlmap[index].url, wg)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-11
      • 2015-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-27
      • 2023-03-03
      相关资源
      最近更新 更多