Есть несколько вариантов решения задачи
передавать не указатель, а значение
package main
import (
"fmt"
"time"
)
var c = make(chan int, 3)
var data = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
func main() {
fmt.Println("Hello, playground")
go save()
go read()
time.Sleep(3 * time.Second)
}
func save() {
for _, val := range data {
c <- val
}
}
func read() {
for {
val := <-c
fmt.Println("read:", val)
}
}
скопировать значение и передать указатель на это значение
package main
import (
"fmt"
"time"
)
var c = make(chan *int)
var data = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
func main() {
fmt.Println("Hello, playground")
go save()
go read()
time.Sleep(3 * time.Second)
}
func save() {
for _, val := range data {
v := val
c <- &v
}
}
func read() {
for {
val := <-c
fmt.Println("read:", *val)
}
}
передать правильный указатель, на элемент данных
package main
import (
"fmt"
"time"
var c = make(chan *int, 5)
var data = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
func main() {
fmt.Println("Hello, playground")
go save()
go read()
time.Sleep(3 * time.Second)
}
func save() {
for i := range data {
c <- &data[i]
}
}
func read() {
for {
val := <-c
fmt.Println("read:", *val)
}
}
Проблема в решении возникает потому, что вы передаёте один и тот же указатель при каждой итерации цикла, а когда вторая горутина читает - данные по этому указателю пишущая горутина уже пишет в этот участок памяти новые данные, именно по этой причине возникают одинаковые данные при выводе.
Вот пример, который покажет, что адрес всегда один и тот же
package main
import (
"fmt"
"time"
)
var c = make(chan *int, 5)
var data = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
func main() {
fmt.Println("Hello, playground")
go save()
go read()
time.Sleep(3 * time.Second)
}
func save() {
for _, val := range data {
c <- &val
fmt.Printf("write: %v\n", &val)
}
}
func read() {
for {
val := <-c
fmt.Println("read:", *val)
}
}
Вывод будет таким (адрес один и тот же)
Hello, playground
write: 0xc000094000
write: 0xc000094000
write: 0xc000094000
write: 0xc000094000
write: 0xc000094000
write: 0xc000094000
...
А в такой реализации (2й пример)
func save() {
for _, val := range data {
v := val
c <- &v
fmt.Printf("write: %v\n", &v)
}
}
тут вывод будет таким (каждый раз новый участок памяти)
Hello, playground
write: 0xc000094000
write: 0xc000094010
write: 0xc000094018
write: 0xc000094020
write: 0xc000094028
write: 0xc000094030
В третьем варианте тоже будут разные указатели.