github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/types/testdata/check/chans.go (about)

     1  package chans
     2  
     3  import "runtime"
     4  
     5  // Ranger returns a Sender and a Receiver. The Receiver provides a
     6  // Next method to retrieve values. The Sender provides a Send method
     7  // to send values and a Close method to stop sending values. The Next
     8  // method indicates when the Sender has been closed, and the Send
     9  // method indicates when the Receiver has been freed.
    10  //
    11  // This is a convenient way to exit a goroutine sending values when
    12  // the receiver stops reading them.
    13  func Ranger[T any]() (*Sender[T], *Receiver[T]) {
    14  	c := make(chan T)
    15  	d := make(chan bool)
    16  	s := &Sender[T]{values: c, done: d}
    17  	r := &Receiver[T]{values: c, done: d}
    18  	runtime.SetFinalizer(r, r.finalize)
    19  	return s, r
    20  }
    21  
    22  // A sender is used to send values to a Receiver.
    23  type Sender[T any] struct {
    24  	values chan<- T
    25  	done <-chan bool
    26  }
    27  
    28  // Send sends a value to the receiver. It returns whether any more
    29  // values may be sent; if it returns false the value was not sent.
    30  func (s *Sender[T]) Send(v T) bool {
    31  	select {
    32  	case s.values <- v:
    33  		return true
    34  	case <-s.done:
    35  		return false
    36  	}
    37  }
    38  
    39  // Close tells the receiver that no more values will arrive.
    40  // After Close is called, the Sender may no longer be used.
    41  func (s *Sender[T]) Close() {
    42  	close(s.values)
    43  }
    44  
    45  // A Receiver receives values from a Sender.
    46  type Receiver[T any] struct {
    47  	values <-chan T
    48  	done chan<- bool
    49  }
    50  
    51  // Next returns the next value from the channel. The bool result
    52  // indicates whether the value is valid, or whether the Sender has
    53  // been closed and no more values will be received.
    54  func (r *Receiver[T]) Next() (T, bool) {
    55  	v, ok := <-r.values
    56  	return v, ok
    57  }
    58  
    59  // finalize is a finalizer for the receiver.
    60  func (r *Receiver[T]) finalize() {
    61  	close(r.done)
    62  }