Passing pointer through channel in Go Lang
Asked Answered
X

2

19

It is possible to pass pointer over channel in go lang? I need to pass struct, do changes in it and have theese changes in the same function from where struct was passed?

I tried

chan <- &data

and I got

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

after this I tried

chan <- *data

and I got

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

So, it is possible to send pointer through channel in Go ir not?

Xanthein answered 30/12, 2013 at 21:56 Comment(0)
B
23

Sure you can, e.g.

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)
}

See in Go Playground.

The error you get tells you that your channel takes a KaVartoti struct, you'll have to create a channel of KaVartoti pointers (a chan *KaVartoti).

At a guess, your duom variable is an array/slice, so if you want to send a pointer to one of the elements, you'd use your first approach of &duom[i]

Blueweed answered 30/12, 2013 at 22:18 Comment(1)
Once should be cautious though that sending and receiving on the same channel, in the same method especially when running in a goroutine like here, makes that channel a 1 way in, 1 way out channel. IOW, do not try this concurrently by iterating and sending multiple values to the channel: you won't get back those values in the same order. But, by blocking on each receive, like done in here in the main, would be ok if that is your use case.Galang
S
-3

Check Following Example:

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)
    }
}
Sturgill answered 1/8, 2018 at 13:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.