github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/internal/test/base/unsafe_OutputAnyParameter_test.go (about)

     1  package base
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  	"unsafe"
     8  )
     9  
    10  func OutputAnyParameter() any {
    11  	fn := func(arg *int) {
    12  		*arg = 123
    13  	}
    14  
    15  	var i int
    16  	fn(&i)
    17  	return i
    18  }
    19  
    20  func ReflectOutputAnyParameter() any {
    21  	type eface struct {
    22  		typ, val unsafe.Pointer
    23  	}
    24  
    25  	fn := func(arg any) {
    26  		var vv any = 123
    27  		reflect.Indirect(reflect.ValueOf(arg)).Set(reflect.ValueOf(vv))
    28  	}
    29  
    30  	var i int
    31  	fn(&i)
    32  	return i
    33  }
    34  
    35  // TODO 判断类型
    36  func UnsafeOutputAnyParameter() any {
    37  	//type user struct {
    38  	//	name string
    39  	//}
    40  	type eface struct {
    41  		typ, val unsafe.Pointer
    42  	}
    43  
    44  	fn := func(arg any) {
    45  		//var val any = user{"test"}
    46  		var val any = 123
    47  		//fmt.Println(reflect.TypeOf(arg).Elem().Name(), reflect.TypeOf(val).Name())
    48  		//*
    49  		t := reflect.TypeOf(arg)
    50  		tt := reflect.TypeOf(val)
    51  		// 一下代码会导致Unsafe出错
    52  		//fmt.Println(t == tt)
    53  
    54  		if tt.String() == tt.String() && t != tt {
    55  			//	panic("could not convert different type!")
    56  		}
    57  		//*/
    58  		dst := (*eface)(unsafe.Pointer(&arg))
    59  		src := (*eface)(unsafe.Pointer(&val))
    60  		//fmt.Println(*(*eface)(dst.val), *(*eface)(src.val))
    61  
    62  		*(*eface)(dst.val) = *(*eface)(src.val)
    63  	}
    64  
    65  	var i int
    66  
    67  	fn(&i)
    68  	return i
    69  }
    70  
    71  func BenchmarkUnsafeOutputAnyParameter(b *testing.B) {
    72  	for n := 0; n < b.N; n++ {
    73  		UnsafeOutputAnyParameter()
    74  	}
    75  }
    76  func TestUnsafeOutputAnyParameter(t *testing.T) {
    77  	for n := 0; n < 100; n++ {
    78  		fmt.Println("Output:", UnsafeOutputAnyParameter())
    79  	}
    80  }
    81  
    82  func BenchmarkOutputAnyParameter(b *testing.B) {
    83  	for n := 0; n < b.N; n++ {
    84  		OutputAnyParameter()
    85  	}
    86  }
    87  
    88  func BenchmarkReflectOutputAnyParameter(b *testing.B) {
    89  	for n := 0; n < b.N; n++ {
    90  		ReflectOutputAnyParameter()
    91  	}
    92  }