0

To illustrate the problem, I wrote some demo codes. See the runnable code below:

package main

import (
    "fmt"
    "time"
)

type structOfChan struct {
    Name     string
    signalCh chan bool
}

func (sc structOfChan) Init() {
    sc.signalCh = make(chan bool, 1)
}

func (sc structOfChan) Notify() {
    sc.signalCh <- true
    fmt.Println(sc.Name, "notified")
}
func main() {
    sc1 := structOfChan{
        Name:     "created with Channel",
        signalCh: make(chan bool, 1),
    }

    sc2 := structOfChan{Name: "created without channel"}
    sc2.Init()
    go func() {
        sc1.Notify()
    }()
    go func() {
        sc2.Notify()
    }()
    time.Sleep(5 * time.Second)

}

The output of above code is created with Channel notified.

That means when you create a struct without signalCh and then pass it to the struct by init, signalCh will block when some value passed to it.

How did this happen? why does the two approach of passing channels make the difference?

Musen
  • 1,244
  • 11
  • 23
  • 1
    You must use pointer receiver for methods that intend to change the receiver (because the receiver is just a copy). When you change it to pointer, it works, see on the [Go Playground](https://play.golang.org/p/iLlPpes8jEa). If you use a non-pointer receiver, the `signalCh` field of the "original" struct remains `nil`, and attempting to send on a `nil` channel blocks forever. For details, see [How does a non initialized channel behave?](https://stackoverflow.com/questions/39015602/how-does-a-non-initialized-channel-behave/39016004#39016004) – icza May 20 '19 at 09:25

1 Answers1

0

https://play.golang.org/p/TIn7esSsRUZ

package main

import (
    "fmt"
    "time"
)

type structOfChan struct {
    Name     string
    signalCh chan bool
}

func (sc *structOfChan) Init() {
    sc.signalCh = make(chan bool, 1)
}

func (sc *structOfChan) Notify() {
    sc.signalCh <- true
    fmt.Println(sc.Name, "notified")
}
func main() {
    sc1 := &structOfChan{
        Name:     "created with Channel",
        signalCh: make(chan bool, 1),
    }

    sc2 := &structOfChan{Name: "created without channel"}
    sc2.Init()
    go func() {
        sc1.Notify()
    }()
    go func() {
        sc2.Notify()
    }()
    time.Sleep(5 * time.Second)

}

output:

created with Channel notified created without channel notified

To be able to modify struct fields, you need to make reciever functions on pointer values

Ankit Deshpande
  • 3,476
  • 1
  • 29
  • 42