Last active
May 17, 2026 14:13
-
-
Save BrandonIrizarry/2d2b7a816795fd98f8a7b9aa5c25eaa6 to your computer and use it in GitHub Desktop.
Non-destructively computing size of buffered channel of struct{} (Go)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import "fmt" | |
| func main() { | |
| r := make(chan struct{}, 2) | |
| r <- struct{}{} | |
| r <- struct{}{} | |
| s := size(r, 0) | |
| // 2 | |
| fmt.Println(s) | |
| // Still 2 | |
| fmt.Println(s) | |
| <-r | |
| s = size(r, 0) | |
| // 1 | |
| fmt.Println(s) | |
| } | |
| // size computes the number of elements buffered inside r. When first calling, s must be 0. | |
| // When the size is finally computed, that figure, before being returned, is used to refill the | |
| // buffered channel with its original contents. This of course works because everything is | |
| // simply a struct{} :) | |
| func size(r chan struct{}, s int) int { | |
| select { | |
| case <-r: | |
| return size(r, s+1) | |
| default: | |
| // Put everything back. | |
| for range s { | |
| r <- struct{}{} | |
| } | |
| return s | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment