Передача указателя через канал в Go Lang

Можно ли передать указатель на канал в 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 или нет?


person Eddwhis    schedule 30.12.2013    source источник


Ответы (2)


Конечно, вы можете, например.

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.

Ошибка, которую вы получаете, говорит вам, что ваш канал использует структуру KaVartoti, вам нужно будет создать канал указателей KaVartoti (a chan *KaVartoti).

Предположительно, ваша переменная duom представляет собой массив/срез, поэтому, если вы хотите отправить указатель на один из элементов, вы должны использовать свой первый подход &duom[i]

person nos    schedule 30.12.2013
comment
Однако следует быть осторожным, поскольку отправка и получение по одному и тому же каналу одним и тем же методом, особенно при работе в goroutine, как здесь, делает этот канал каналом с 1 входом и 1 выходом. IOW, не пытайтесь делать это одновременно, повторяя и отправляя несколько значений в канал: вы не получите эти значения в том же порядке. Но блокировка при каждом получении, как это сделано здесь, в основном, будет в порядке, если это ваш вариант использования. - person eduncan911; 01.04.2016

Проверьте следующий пример:

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)
    }
}
person Rahul Shewale    schedule 01.08.2018