github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/compile/syntax/testdata/chans.go (about)

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