18

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?

coanor
  • 3,746
  • 4
  • 50
  • 67
Eddwhis
  • 1,124
  • 2
  • 16
  • 33

2 Answers2

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]

Community
  • 1
  • 1
nos
  • 223,662
  • 58
  • 417
  • 506
  • 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. – eduncan911 Apr 01 '16 at 05:27
-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)
    }
}
Rahul Shewale
  • 1,038
  • 10
  • 12