Source file test/typeparam/issue50690a.go

     1  // run
     2  
     3  // Copyright 2022 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  package main
     8  
     9  import (
    10  	"fmt"
    11  )
    12  
    13  // Numeric expresses a type constraint satisfied by any numeric type.
    14  type Numeric interface {
    15  	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 |
    16  		~int | ~int8 | ~int16 | ~int32 | ~int64 |
    17  		~float32 | ~float64 |
    18  		~complex64 | ~complex128
    19  }
    20  
    21  // Sum returns the sum of the provided arguments.
    22  func Sum[T Numeric](args ...T) T {
    23  	var sum T
    24  	for i := 0; i < len(args); i++ {
    25  		sum += args[i]
    26  	}
    27  	return sum
    28  }
    29  
    30  // Ledger is an identifiable, financial record.
    31  type Ledger[T ~string, K Numeric] struct {
    32  	// ID identifies the ledger.
    33  	ID_ T
    34  
    35  	// Amounts is a list of monies associated with this ledger.
    36  	Amounts_ []K
    37  
    38  	// SumFn is a function that can be used to sum the amounts
    39  	// in this ledger.
    40  	SumFn_ func(...K) K
    41  }
    42  
    43  // Field accesses through type parameters are disabled
    44  // until we have a more thorough understanding of the
    45  // implications on the spec. See issue #51576.
    46  // Use accessor methods instead.
    47  
    48  func (l Ledger[T, _]) ID() T               { return l.ID_ }
    49  func (l Ledger[_, K]) Amounts() []K        { return l.Amounts_ }
    50  func (l Ledger[_, K]) SumFn() func(...K) K { return l.SumFn_ }
    51  
    52  func PrintLedger[
    53  	T ~string,
    54  	K Numeric,
    55  	L interface {
    56  		~struct {
    57  			ID_      T
    58  			Amounts_ []K
    59  			SumFn_   func(...K) K
    60  		}
    61  		ID() T
    62  		Amounts() []K
    63  		SumFn() func(...K) K
    64  	},
    65  ](l L) {
    66  	fmt.Printf("%s has a sum of %v\n", l.ID(), l.SumFn()(l.Amounts()...))
    67  }
    68  
    69  func main() {
    70  	PrintLedger(Ledger[string, int]{
    71  		ID_:      "fake",
    72  		Amounts_: []int{1, 2, 3},
    73  		SumFn_:   Sum[int],
    74  	})
    75  }
    76  

View as plain text