Исходники и презентации

This commit is contained in:
2025-05-23 07:26:39 +03:00
parent aa948179d5
commit 02d8430a3a
514 changed files with 13773 additions and 0 deletions

View File

@ -0,0 +1,30 @@
package main
import (
"fmt"
"reflect"
)
type CloneableMixin[T any] struct{}
func (m CloneableMixin[T]) Clone() *T {
return new(T)
}
type Data1 struct {
CloneableMixin[Data1]
}
type Data2 struct {
CloneableMixin[Data2]
}
func main() {
data1 := Data1{}
clone1 := data1.Clone()
fmt.Println(reflect.TypeOf(clone1)) // *main.Data1
data2 := Data2{}
clone2 := data2.Clone()
fmt.Println(reflect.TypeOf(clone2)) // *main.Data2
}

View File

@ -0,0 +1,19 @@
package main
import "fmt"
type Data struct {
Value string
}
func (d Data) GetValue() string {
return d.Value
}
type ValueGetter interface {
GetValue() string
}
func Print[T ValueGetter](value T) {
fmt.Println(value.GetValue())
}

View File

@ -0,0 +1,19 @@
package main
import "fmt"
type Data1 struct {
Value string
}
type Data2 struct {
Value string
}
func Print1[T any](value T) {
fmt.Println(value.Value) // compilation error
}
func Print2[T Data1 | Data2](value T) {
fmt.Println(value.Value) // compilation error
}

View File

@ -0,0 +1,29 @@
package main
type Stringer interface {
String() string
}
func ToString[T Stringer](values ...T) []string {
result := make([]string, 0, len(values))
for idx := range values {
result = append(result, values[idx].String())
}
return result
}
type Data struct{}
func (d Data) String() string {
return "string"
}
func main() {
data := Data{}
var idata Stringer = data
_ = ToString(data)
_ = ToString(idata)
_ = ToString(100)
}

View File

@ -0,0 +1,45 @@
package main
type Integer1 interface {
int | int16 | int32 | int64
}
type Integer2 interface {
~int | ~int16 | ~int32 | ~int64
}
func Process1[T1 Integer1](value T1) {
// ..
}
func Process11[T2 interface{ int | int16 | int32 | int64 }](value T2) {
// ..
}
func Process12[T2 int | int16 | int32 | int64](value T2) { // interface{} can be omitted
// ..
}
func Process2[T2 Integer2](value T2) {
// ..
}
type MyInt1 int
type MyInt2 MyInt1
type MyIntAlias1 = int
type MyIntAlias2 = MyIntAlias1
func main() {
Process1(int(100))
Process1(MyInt1(100))
Process1(MyInt2(100))
Process1(MyIntAlias1(100))
Process1(MyIntAlias2(100))
Process2(int(100))
Process2(MyInt1(100))
Process2(MyInt2(100))
Process1(MyIntAlias1(100))
Process1(MyIntAlias2(100))
}

View File

@ -0,0 +1,26 @@
package main
type MyInt int
func (i MyInt) String() string {
return "number"
}
type Constraint interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
String() string
any
// Do()
// interface{ Do() }
// ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
}
func Do[T Constraint](value T) {
// ...
}
func main() {
var value MyInt
Do(value)
}

View File

@ -0,0 +1,14 @@
package main
// generics restriction
type _ interface {
int | ~int // compilation error
}
type _ interface {
interface{ int } | interface{ ~int } // ok
}
type _ interface {
int | interface{ ~int } // ok
}

View File

@ -0,0 +1,21 @@
package main
type _ interface {
[]int | comparable // compilation error
}
type _ interface {
string | error // compilation error
}
type _ interface {
string | interface{ Do() } // compilation error
}
type _ interface {
string | interface{ int } // ok
}
type _ interface {
string | interface{} // ok
}

View File

@ -0,0 +1,24 @@
package main
// constraint
type Unsigned interface {
uint | uint8 | uint16 | uint32 | uint64
}
type Slice[T any] []T
type SliceConstaint[E Unsigned] interface {
Slice[E]
}
func Do[E Unsigned, T SliceConstaint[E]](values T) {
// ...
}
func main() {
var slice1 Slice[uint8]
var slice2 Slice[uint16]
Do(slice1)
Do(slice2)
}

View File

@ -0,0 +1,17 @@
package main
import "fmt"
func Decorator[T any](fn func(T), decorator func(T) T) func(T) {
return func(input T) {
fn(decorator(input))
}
}
func main() {
print := func(value int) { fmt.Println(value) }
double := func(value int) int { return value * value }
decorated := Decorator(print, double)
decorated(10)
}

View File

@ -0,0 +1,14 @@
package main
// constraint
type Signed interface {
int | int8 | int16 | int32 | int64
}
type Counter struct {
value int64
}
func Add[T Signed](c *Counter, value T) {
c.value += int64(value)
}

View File

@ -0,0 +1,14 @@
package main
// constraint
type Signed interface {
int | int8 | int16 | int32 | int64
}
type Counter struct {
value int64
}
func (c *Counter) Add[T Signed](value T) { // compilation erro
c.value += int64(value)
}

View File

@ -0,0 +1,15 @@
package main
type S struct{}
func (S) Bar() {}
type C interface {
S
Foo()
}
func foobar[T C](value T) {
value.Foo()
value.Bar() // compilation error
}

View File

@ -0,0 +1,37 @@
package main
import "fmt"
type Set[K comparable] struct {
data map[K]struct{}
}
func NewSet[K comparable]() Set[K] {
return Set[K]{
data: make(map[K]struct{}),
}
}
func (s *Set[K]) Insert(key K) {
s.data[key] = struct{}{}
}
func (s *Set[K]) Erase(key K) {
delete(s.data, key)
}
func (s *Set[K]) Contains(key K) bool {
_, found := s.data[key]
return found
}
// skipping like with function
func (s *Set[_]) Print() {
fmt.Println(s.data)
}
func main() {
set := NewSet[string]()
set.Insert("key")
set.Erase("key")
}

View File

@ -0,0 +1,11 @@
package main
func Process[T any](data ...T) {
// processing
}
func main() {
Process(2, 5, 10)
Process("one", "two")
Process(0.3)
}

View File

@ -0,0 +1,13 @@
package main
func process1[T []byte | [2]byte | string](value T) {
_ = value[0]
}
func process2[T map[int]string](value T) {
_ = value[0]
}
func process3[T map[int]string|[]byte](value T) {
_ = value[0]
}

View File

@ -0,0 +1,6 @@
package main
func process[T ~string | ~[]byte](value T, index int) {
_ = value[index]
value[index] = byte('a') // error
}

View File

@ -0,0 +1,10 @@
package main
func process1[T int]() {
const value T = 5 // compilation error
}
func process2[T int]() {
var value T = 5 // ok
_ = value
}

View File

@ -0,0 +1,13 @@
package main
func process1[T int32 | int64](value *T) {
*value = *value + 1 // ok
}
func process2[T *int32 | *int64](value T) {
*value = *value + 1 // compilation error
}
func process3[T *Int, Int int32 | int64](value T) {
*value = *value + 1 // ok
}

View File

@ -0,0 +1,25 @@
package main
import "unsafe"
func store[T any](pointer unsafe.Pointer, value T) {
*(*T)(pointer) = value
}
func load[T any](pointer unsafe.Pointer) T {
return *(*T)(pointer)
}
func main() {
var pointer1 unsafe.Pointer // not initialized
var pointer2 unsafe.Pointer // not initialized
store[int16](pointer1, 100)
store[int32](pointer2, 200)
value1 := load[int16](pointer1)
value2 := load[int32](pointer2)
_ = value1
_ = value2
}

View File

@ -0,0 +1,26 @@
package main
func GetKeys(data map[string]int) []string {
keys := make([]string, 0, len(data))
for key := range data {
keys = append(keys, key)
}
return keys
}
// any -> alias for interface{}
// comparable -> constraint for != and ==
func GetKeysGeneric[K comparable, V any](data map[K]V) []K {
keys := make([]K, 0, len(data))
for key := range data {
keys = append(keys, key)
}
return keys
}
func main() {
GetKeys(map[string]int{})
GetKeysGeneric[int, int](map[int]int{})
}

View File

@ -0,0 +1,25 @@
package main
func MaxInt(lhs, rhs int) int {
if lhs >= rhs {
return lhs
} else {
return rhs
}
}
func MaxUInt(lhs, rhs uint) uint {
if lhs >= rhs {
return lhs
} else {
return rhs
}
}
func main() {
var lhs1, rhs1 int = 10, 20
_ = MaxInt(lhs1, rhs1)
var lhs2, rhs2 uint = 10, 20
_ = MaxUInt(lhs2, rhs2)
}

View File

@ -0,0 +1,32 @@
package main
// constraint
type Signed interface {
int | int8 | int16 | int32 | int64
}
// constraint
type Unsigned interface {
uint | uint8 | uint16 | uint32 | uint64
}
// constraint
type Integer interface {
Signed | Unsigned
}
func Max[T Integer](lhs, rhs T) T {
if lhs >= rhs {
return lhs
} else {
return rhs
}
}
func main() {
var lhs1, rhs1 int = 10, 20
_ = Max[int](lhs1, rhs1)
var lhs2, rhs2 uint = 10, 20
_ = Max[uint](lhs2, rhs2)
}

View File

@ -0,0 +1,16 @@
package main
type Data struct{}
func (d Data) Do1() {}
type Constraint interface {
Data
Do2()
}
// generics restriction
func GenericDo[T Constraint](value T) {
value.Do1() // compilation error
value.Do2() // ok
}

View File

@ -0,0 +1,9 @@
package main
type T[T1 any, T2 any] struct{}
type TypeAlias1 = T[string, int]
type TypeAlias2[T1 any] = T[T1, int]
type TypeDefinition1 T[string, int]
type TypeDefinition2[T1 any] T[T1, int]

View File

@ -0,0 +1,56 @@
package main
import (
"fmt"
"reflect"
"unsafe"
)
type Data struct {
age int8
address string
}
func getFieldOffset(instance interface{}, fieldName string) (uintptr, error) {
instanceValue := reflect.ValueOf(instance)
if instanceValue.Kind() != reflect.Ptr {
return 0, fmt.Errorf("the first parameter must be a pointer to a struct")
}
instanceType := instanceValue.Type().Elem()
field, found := instanceType.FieldByName(fieldName)
if !found {
return 0, fmt.Errorf("field '%s' not found in the struct", fieldName)
}
return field.Offset, nil
}
func AssignPrivateField[T any, V any](src *T, field string, value V) error {
offset, err := getFieldOffset(src, field)
if err != nil {
return fmt.Errorf("get offset: %w", err)
}
fieldPtr := (*V)(unsafe.Add(unsafe.Pointer(src), offset))
*fieldPtr = value
return nil
}
func ReadPrivateField[T any, V any](src *T, field string) (V, error) {
var output V
offset, err := getFieldOffset(src, field)
if err != nil {
return output, fmt.Errorf("get offset: %w", err)
}
output = *(*V)(unsafe.Add(unsafe.Pointer(src), offset))
return output, nil
}
func main() {
data := &Data{}
_ = AssignPrivateField(data, "address", "Moscow")
fmt.Println(data)
}

View File

@ -0,0 +1,24 @@
package main
import (
"fmt"
"reflect"
"unsafe"
)
type Data struct {
value string
}
func main() {
data := Data{
value: "it's a secret",
}
field := reflect.ValueOf(&data).Elem().FieldByName("value")
pointer := unsafe.Pointer(field.UnsafeAddr())
strPtr := (*string)(pointer)
*strPtr = "it's not a secret"
fmt.Println(data.value)
}

View File

@ -0,0 +1,15 @@
package main
import (
"fmt"
"reflect"
)
func main() {
var value float64 = 3.14
v := reflect.ValueOf(value) // copy of value
//v.SetFloat(2.7)
//v.Addr()
fmt.Println("settability of v:", v.CanSet())
}

View File

@ -0,0 +1,32 @@
package main
import (
"fmt"
"reflect"
)
func main() {
ch := make(chan string, 2)
vCh := reflect.ValueOf(ch)
vCh.Send(reflect.ValueOf("Go"))
succeeded := vCh.TrySend(reflect.ValueOf("C++"))
fmt.Println("C++", succeeded)
succeeded = vCh.TrySend(reflect.ValueOf("Java"))
fmt.Println("Java", succeeded)
fmt.Println(vCh.Len(), vCh.Cap())
value, ok := vCh.Recv()
fmt.Println(value, ok)
value, ok = vCh.TryRecv()
fmt.Println(value, ok)
value, ok = vCh.TryRecv()
fmt.Println(value, ok)
vCh.Close()
}

View File

@ -0,0 +1,16 @@
package main
import (
"fmt"
"reflect"
)
func main() {
var str string
var number int
var slice []int
fmt.Println("str:", reflect.ValueOf(str).Comparable())
fmt.Println("number:", reflect.ValueOf(number).Comparable())
fmt.Println("slice:", reflect.ValueOf(slice).Comparable())
}

View File

@ -0,0 +1,20 @@
package main
import (
"fmt"
"reflect"
)
func main() {
vData := reflect.ValueOf([]int{1, 2, 3})
tData := vData.Type()
t1 := reflect.TypeOf(&[3]int{})
t2 := reflect.TypeOf([3]int{})
fmt.Println(tData.ConvertibleTo(t1))
fmt.Println(tData.ConvertibleTo(t2))
fmt.Println(vData.CanConvert(t1))
fmt.Println(vData.CanConvert(t2))
}

View File

@ -0,0 +1,22 @@
package main
import (
"fmt"
"reflect"
)
func main() {
dataStruct := reflect.StructOf([]reflect.StructField{
{Name: "Age", Type: reflect.TypeOf("abc")},
})
fmt.Println("dataStruct:", dataStruct)
dataArray := reflect.ArrayOf(5, reflect.TypeOf(123))
fmt.Println("dataArray:", dataArray)
dataPointer := reflect.PointerTo(dataArray)
fmt.Println("dataPointer:", dataPointer)
}

View File

@ -0,0 +1,21 @@
package main
import (
"fmt"
"reflect"
)
func main() {
var z = 100
var y = &z
var x interface{} = y
v := reflect.ValueOf(&x)
vx := v.Elem()
vy := vx.Elem()
vz := vy.Elem()
fmt.Println(vx, vy, vz)
vz.Set(reflect.ValueOf(200))
fmt.Println(vx, vy, vz)
}

View File

@ -0,0 +1,25 @@
package main
import (
"fmt"
"reflect"
)
func main() {
var value float64 = 3.14
v := reflect.ValueOf(&value) // copy of value
fmt.Println("type of v:", v.Type())
fmt.Println("settability of v:", v.CanSet())
fmt.Println("addresability of v:", v.CanAddr())
fmt.Println("type of v.Elem():", v.Elem().Type()) // dereference
fmt.Println("settability of v.Elem():", v.Elem().CanSet()) // dereference
fmt.Println("addresability of v.Elem():", v.Elem().CanAddr()) // dereference
v.Elem().SetFloat(2.7)
fmt.Println(v.Elem().Addr())
fmt.Println("value:", value)
fmt.Println("address:", &value)
}

View File

@ -0,0 +1,33 @@
package main
import (
"fmt"
"reflect"
)
type Vector struct {
X int
Y int
}
func (v Vector) Add(factor int) int {
return (v.X + v.Y) * factor
}
func main() {
vector := Vector{X: 5, Y: 15}
vVector := reflect.ValueOf(vector)
vAdd := vVector.MethodByName("Add")
vResults := vAdd.Call([]reflect.Value{reflect.ValueOf(2)})
fmt.Println(vResults[0].Int())
negative := func(x int) int {
return -x
}
vNegative := reflect.ValueOf(negative)
vResults = vNegative.Call([]reflect.Value{reflect.ValueOf(100)})
fmt.Println(vResults[0].Int())
}

View File

@ -0,0 +1,32 @@
package main
import (
"fmt"
"reflect"
)
func InvertSlice(args []reflect.Value) []reflect.Value {
inSlice, length := args[0], args[0].Len()
outSlice := reflect.MakeSlice(inSlice.Type(), 0, length)
for idx := length - 1; idx >= 0; idx-- {
element := inSlice.Index(idx)
outSlice = reflect.Append(outSlice, element)
}
return []reflect.Value{outSlice}
}
func Bind(value interface{}, fn func([]reflect.Value) []reflect.Value) {
invert := reflect.ValueOf(value).Elem()
invert.Set(reflect.MakeFunc(invert.Type(), fn))
}
func main() {
var invertInts func([]int) []int
Bind(&invertInts, InvertSlice)
fmt.Println(invertInts([]int{2, 3, 5}))
var invertStrs func([]string) []string
Bind(&invertStrs, InvertSlice)
fmt.Println(invertStrs([]string{"C++", "Go"}))
}

View File

@ -0,0 +1,20 @@
package main
import (
"fmt"
"reflect"
)
type Interface interface {
Method()
}
type Data struct{}
func (c Data) Method() {}
func main() {
dataType := reflect.TypeOf(Data{})
interfaceType := reflect.TypeOf((*Interface)(nil)).Elem()
fmt.Println("implements:", dataType.Implements(interfaceType))
}

View File

@ -0,0 +1,13 @@
package main
import (
"fmt"
"reflect"
)
func main() {
var value float32 = 3.14
v := reflect.ValueOf(value)
iValue := v.Interface()
fmt.Println(iValue.(float32))
}

View File

@ -0,0 +1,13 @@
package main
import (
"reflect"
)
func main() {
pointer1 := reflect.ValueOf(new(int)).Pointer() // unsafe
pointer2 := reflect.ValueOf(new(int)).UnsafePointer() // safe
_ = pointer1
_ = pointer2
}

View File

@ -0,0 +1,18 @@
package main
import (
"fmt"
"reflect"
)
func main() {
data := map[string]int{"data1": 100, "data2": 200}
vData := reflect.ValueOf(data)
vData.SetMapIndex(reflect.ValueOf("data1"), reflect.ValueOf(1000))
vData.SetMapIndex(reflect.ValueOf("data2"), reflect.ValueOf(2000))
for it := vData.MapRange(); it.Next(); {
fmt.Println(it.Key(), it.Value())
}
}

View File

@ -0,0 +1,17 @@
package main
import (
"fmt"
"reflect"
)
func main() {
var value1 reflect.Value
fmt.Println(value1)
value2 := reflect.ValueOf((*int)(nil)).Elem()
fmt.Println(value2)
value3 := reflect.ValueOf([]interface{}{nil}).Index(0)
fmt.Println(value3)
}

View File

@ -0,0 +1,24 @@
package main
import (
"fmt"
"reflect"
)
func main() {
ch := make(chan int, 1)
vch := reflect.ValueOf(ch)
succeed := vch.TrySend(reflect.ValueOf(100))
fmt.Println(succeed, vch.Len(), vch.Cap())
branches := []reflect.SelectCase{
{Dir: reflect.SelectDefault},
{Dir: reflect.SelectRecv, Chan: vch},
}
index, vRecv, recvOk := reflect.Select(branches)
fmt.Println(index, vRecv, recvOk)
vch.Close()
}

View File

@ -0,0 +1,30 @@
package main
import (
"fmt"
"reflect"
)
type Data struct {
Count int
Title string
}
func (d Data) Do() {}
func main() {
data := Data{}
tData := reflect.TypeOf(data)
fmt.Println("Kind:", tData.Kind())
fmt.Println("PkgPath:", tData.PkgPath())
fmt.Println("NumField:", tData.NumField())
fmt.Println("Field(0):", tData.Field(0).Name)
fmt.Println("Field(1):", tData.Field(1).Name)
fmt.Println("NumMethod:", tData.NumMethod())
fmt.Println("Method(0):", tData.Method(0).Name)
fmt.Println("Method(0).NumIn:", tData.Method(0).Type.NumIn())
fmt.Println("Method(0).NumOut:", tData.Method(0).Type.NumOut())
}

View File

@ -0,0 +1,24 @@
package main
import (
"fmt"
"reflect"
)
type Data struct {
X int `json:"x" xml:"name"`
Y bool `json:"y,omitempty"`
}
func main() {
t := reflect.TypeOf(Data{})
tXTag := t.Field(0).Tag
tYTag := t.Field(1).Tag
fmt.Println(reflect.TypeOf(tXTag), reflect.TypeOf(tYTag))
value, present := tXTag.Lookup("json")
fmt.Println(value, present)
value, present = tYTag.Lookup("json")
fmt.Println(value, present)
}

View File

@ -0,0 +1,23 @@
package main
import (
"fmt"
"reflect"
)
func main() {
var value float64 = 3.4
// неявное преобразование в пустой интерфейс
fmt.Println("type:", reflect.TypeOf(value)) // func TypeOf(i any) reflect.Type
fmt.Println("type:", reflect.ValueOf(value)) // func ValueOf(i any) reflect.Value
equal := reflect.ValueOf(value).Type() == reflect.TypeOf(value)
fmt.Println("equal:", equal)
kind := reflect.ValueOf(value).Kind()
fmt.Println("equal reflect.Float64:", reflect.Float64 == kind)
value = reflect.ValueOf(value).Float()
_ = value
}

View File

@ -0,0 +1,17 @@
package main
import (
"fmt"
"reflect"
)
func main() {
var x uint8 = 10
v := reflect.ValueOf(x)
fmt.Println("type:", v.Type())
fmt.Println("kind:", v.Kind())
x = uint8(v.Uint()) // uint64
_ = x
}

View File

@ -0,0 +1,22 @@
package main
import (
"fmt"
"reflect"
)
type Data struct {
Value1 int
value2 int
}
func main() {
data := Data{Value1: 100, value2: 200}
v := reflect.ValueOf(&data).Elem()
t := v.Type()
for idx := 0; idx < v.NumField(); idx++ {
field := v.Field(idx)
fmt.Println(t.Field(idx).Name, field.CanSet(), field.CanAddr())
}
}

View File

@ -0,0 +1,23 @@
package main
import (
"fmt"
"reflect"
)
type IntAlias = int
type IntDefinition int
func main() {
var value1 IntAlias = 7
v1 := reflect.ValueOf(value1)
fmt.Println("alias type:", v1.Type())
fmt.Println("alias kind:", v1.Kind())
var value2 IntDefinition = 7
v2 := reflect.ValueOf(value2)
fmt.Println("definition type:", v2.Type())
fmt.Println("definition kind:", v2.Kind())
}

View File

@ -0,0 +1,23 @@
package main
type NewType[T any] T // may not be used as the source types
type Set1[K comparable] map[K]struct{}
type Set2[K comparable] = map[K]struct{} // generic type aliases are not supported
type SetBool1 Set1[bool]
type SetBool2 = Set1[bool]
type Comparable1 comparable
type Comparable2 = comparable
type Constraint1 interface{ int | uint }
type Constraint2 = interface{ int | uint }
func main() {
setStr := Set1[string]{}
_ = setStr
setBool := SetBool1{}
_ = setBool
}

View File

@ -0,0 +1,41 @@
package main
import "fmt"
func IsInt1[T any](x T) bool {
_, ok := any(x).(int)
return ok
}
func Is1[T int | string](x T) {
switch any(x).(type) {
//case T:
// fmt.Println("int")
case int:
fmt.Println("int")
case string:
fmt.Println("string")
}
}
func IsInt2[T any](x T) bool {
_, ok := x.(int) // cannot use type assertion on type parameter
return ok
}
func Is2[T int | string](x T) {
switch x.(type) { // cannot use type switch on type parameter
case int:
fmt.Println("int")
case string:
fmt.Println("string")
}
}
func main() {
fmt.Println("IsInt(100):", IsInt1(100))
fmt.Println(`IsInt("100"):`, IsInt1("100"))
Is1("100")
Is1(100)
}

View File

@ -0,0 +1,38 @@
package main
import "fmt"
func Create[T any]() *T {
return new(T)
}
func Print[T any](value T) {
fmt.Println()
}
func MultiplePrint[T1 any, T2 any](lhs T1, rhs T2) {
fmt.Println(lhs, rhs)
}
type Data[T any] struct {
Value T
}
func main() {
// without infence
value1 := Create()
_ = value1
var value2 *int = Create()
_ = value2
// with infence
Print(100)
Print("hello")
MultiplePrint(100, "hello")
// without infence
data1 := Data{}
_ = data1
data2 := Data{Value: 100}
_ = data2
}

View File

@ -0,0 +1,9 @@
package main
type Base1[Derived any] struct {
Derived // compilation error
}
type Base2[Derived any] struct {
d Derived // ok
}

View File

@ -0,0 +1,29 @@
package main
func Process1[T any, K comparable, V any](key K, value V) {
// implementation
}
func Process2[K comparable, V any, T any](key K, value V) {
// implementation
}
func Process3[T any, _ comparable, _ any](value T) {
// implementation
}
func Process4[T1, T2 any, _ comparable](value1 T1, value2 T2) {
// implementation
}
func Process5[_ any, _ any]() {
// implementation
}
func main() {
Process1[int]("key", []int{100}) // partial argument list only with prefix
Process2[int]("key", []int{100}) // compilation error with suffix
Process3[int, string, float32](100)
Process2[int, _, float32](100) // compilation error
}

View File

@ -0,0 +1,23 @@
package main
type Creator[T any] func() T
func NewInstance[T any](creator Creator[T]) T {
return creator()
}
type (
Book struct{}
Game struct{}
)
func main() {
bookCreator := func() Book { return Book{} }
gameCreator := func() Game { return Game{} }
book := NewInstance(bookCreator)
_ = book
game := NewInstance(gameCreator)
_ = game
}

View File

@ -0,0 +1,14 @@
package main
func process1[T1 int, T2 *T1]() {
}
func process2[T1 *T2, T2 int]() {
}
func process3[T1 *T1]() {
}
func process4[T ~string | ~int, A ~[2]T, B ~chan T]() {
}