The asymmetry
Starting a goroutine takes two characters. Stopping one takes a plan, and the language provides no default.
There is no kill, no interrupt, and no timeout on a goroutine. A goroutine ends exactly one way: its function returns. Everything else is a mechanism for persuading it to return.
That asymmetry is deliberate. Killing a thread from outside is unsafe in every language that has tried it, because the victim may hold a lock, be mid-write, or own a resource nobody else can release. Go declined to offer it.
The consequence is a question with no default answer, and it must be answered for every goroutine you start: what makes this return?
If the answer is that it finishes its work, fine. If the answer is that it loops until something tells it to stop, then something must be able to tell it, and building that channel is your job.
A goroutine with no answer is a leak waiting for the right input.

