Skip to content

Instantly share code, notes, and snippets.

@vxcute
Created February 28, 2023 03:51
Show Gist options
  • Save vxcute/72d2e83b7106191b622f428edd5d3007 to your computer and use it in GitHub Desktop.
Save vxcute/72d2e83b7106191b622f428edd5d3007 to your computer and use it in GitHub Desktop.
// custom channels in go
// I learned how go-channels can be implemented in C++ and decided to make it in go haha wtf
// I saw this https://st.xorian.net/blog/2012/08/go-style-channel-in-c/ great article
package main
import (
"log"
"sync"
)
type Channel[T any] struct {
mu sync.Mutex
queue []T
closed bool
}
func NewChannel[T any]() *Channel[T] {
return &Channel[T]{}
}
func (c *Channel[T]) Set(v T) {
c.mu.Lock()
defer c.mu.Unlock()
if c.closed {
log.Panic("channel is closed")
}
c.queue = append(c.queue, v)
}
func (c *Channel[T]) Get(v *T) bool {
c.mu.Lock()
defer c.mu.Unlock()
if len(c.queue) == 0 {
return false
}
*v = c.queue[0]
c.queue = c.queue[1:]
return true
}
func (c *Channel[T]) Close() {
c.mu.Lock()
defer c.mu.Unlock()
c.closed = true
}
func main() {
channel := NewChannel[int]()
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
for i := 0; i < 5; i++ {
channel.Set(i)
}
channel.Close()
wg.Done()
}()
wg.Wait()
x := 0
for channel.Get(&x) {
println(x)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment