当前位置:网站首页>5. golang generics and reflection
5. golang generics and reflection
2022-06-10 18:46:00 【He Yi Qingfeng】
1. Generic
1.1 Definition
- Generic Life cycle Only at compile time , Designed to generate code for programmers , Reduce the duplication of code
- When comparing the size of two numbers , When there are no generics , Only the incoming type is different , We're going to write an identical function , If you have generics, you can reduce this kind of code
1.2 Example
// SumInts take map The value of the combined , If the data types to be added are different , Then you need to define two
func SumInts(m map[string]int64) int64 {
var s int64
for _, v := range m {
s += v
}
return s
}
func SumFloats(m map[string]float64) float64 {
var s float64
for _, v := range m {
s += v
}
return s
}
If you use generics, you only need to define generic methods ( If you report a compilation error , yes idea Version is too low , Upgrade the version , But there's no problem running )

func main() {
ints := make(map[string]int64, 5)
ints["name"] = 5
ints["value"] = 6
floats := make(map[string]float64, 5)
floats["name"] = 5.6
floats["value"] = 6.5
fmt.Printf("Gnneric sums: %v and %v\n",
SumIntsOrFloats[string, int64](ints),
SumIntsOrFloats[string, float64](floats))
// You can delete the type
fmt.Printf("Gnneric sums: %v and %v\n",
SumIntsOrFloats(ints),
SumIntsOrFloats(floats))
}
//SumIntsOrFloats Define generic methods
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
1.3 Custom generic types
- any: representative go All the built-in types , Equivalent to interface {}
- comparable: representative go Built in comparable types :int、uint、float、bool、struct、 Pointer and other comparable types
- ~ Symbol : A derived type used to represent a modified type
// Type constraint
type Number interface {
int64 | float64
}
// The current class can be used for type constraints
func SumIntsNumbers[K comparable, V Number](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
1.4 Generics and switch Use a combination of
func main() {
fmt.Println(Get(12))
}
//go You cannot directly associate generics with switch Use
func Get[T any](t T) T {
var ti interface{
} = &t
switch v := ti.(type) {
case *int:
*v = 18
}
return t
}
1.5 Generic combat
1.5.1 Use generic definitions Json analytic method
// Get the type and value through reflection according to the incoming type
func typeFunc[E any](v any, e *E) *E {
valueOf := reflect.ValueOf(v)
typeOf := reflect.TypeOf(v)
if k := typeOf.Kind(); k == reflect.Slice {
json.Unmarshal(valueOf.Bytes(), e)
}
return e
}
func main() {
user1 := &User{
}
user1 = typeFunc[User](marshal, user1)
fmt.Printf("%+v", user1)
}
2. Reflection
2.1 Definition
Golang Provides a mechanism , At compile time Without knowing the type , can Update variables 、 Runtime Check the value 、 Calling method And directly to them Operate on the layout The mechanism of , It's called reflection .
2.2 Method
| Method | explain | return |
|---|---|---|
| reflect.ValueOf() | Get the value of the data in the input parameter interface , If it is not empty, it returns 0, Note that the current method will make the object escape into heap space | The return is Value object |
| reflect.TypeOf() | Dynamically obtain the type of value in the input parameter interface , If it is empty, return nil | The return is Type object |
Value
type Value struct { typ *rtype // Save the value of the type ptr unsafe.Pointer // Pointer types flag // Get the pointing address of the value , Used to modify values by reflection Elem() Type // to value Set the value Set() }Type
type Type interface { // Get the method according to the index Method(int) Method // Get the method by name MethodByName(string) (Method, bool) // Get the number of methods NumMethod() int // Get structure name Name() string // Get package path PkgPath() string // Get the current type Kind() Kind // Determine whether the current type implements the interface Implements(u Type) bool // Returns... Of type in bits x Bits() int // Get the type of property value , Type must be :Array、Chan、Map、Pointer、Slice, Otherwise, the report will be wrong Elem() Type // Get the specified value Field(i int) StructField // Get the nested fields of the corresponding index FieldByIndex(index []int) StructField // Get the corresponding field by name FieldByName(name string) (StructField, bool) FieldByNameFunc(match func(string) bool) (StructField, bool) ..... }
2.3 Reflection reading
func stringReflect() {
name := " This is the first reflection string "
valueOf := reflect.ValueOf(name)
typeOf := reflect.TypeOf(name)
fmt.Println(valueOf)
fmt.Println(typeOf)
}

type Name struct {
Name string
Age string `use:"Ok"`
}
func (n Name) Show() {
fmt.Println(n.Name)
}
func structReflect() {
name := Name{
Name: " This is a reflective structure ",
}
valueOf := reflect.ValueOf(name)
typeOf := reflect.TypeOf(name)
fmt.Printf("value value :%+v\n", valueOf)
fmt.Printf(" Type the name :%s\n", typeOf.Name())
methodNum := typeOf.NumMethod()
fmt.Printf(" Get the number of methods :%d", methodNum)
for i := 0; i < methodNum; i++ {
method := typeOf.Method(i)
fmt.Printf("%v\t", method.Name)
}
fmt.Println()
methodByName, _ := typeOf.MethodByName("Show")
fmt.Printf(" according to Show Find the specified method :%v\n", methodByName)
// Determine whether the current interface is implemented , Because the interface type cannot create an instance , So the nil Force to *IName type
implements := typeOf.Implements(reflect.TypeOf((*IName)(nil)).Elem())
fmt.Printf(" Current type :%s, Whether the interface is implemented :%s,%v\n", typeOf.Name(), "IName", implements)
fieldNum := typeOf.NumField()
for i := 0; i < fieldNum; i++ {
field := typeOf.Field(i)
fmt.Printf(" Field name :%v\t", field.Name)
if lookup, ok := field.Tag.Lookup("use") ; ok {
fmt.Printf(" Get tag :%v", lookup)
}
}
}
2.4 Reflex action
func setValue() {
name := Name{
Name: " This is a reflective structure ",
}
valueOf := reflect.ValueOf(&name)
fmt.Printf(" Before setting the value :%+v\n", valueOf)
// Get the address value
valueOf = valueOf.Elem()
name1 := Name{
Name: " This is the value set by reflection ",
}
valueOf.Set(reflect.ValueOf(name1))
fmt.Printf(" After setting the value :%+v\n", valueOf)
// Modify field values
fieldValueOf := valueOf.FieldByName("Name")
fieldValueOf.SetString(" This is the value after modifying the field ")
fmt.Printf(" After modifying the field :%v\n", name.Name)
// Calling method
methodByName := valueOf.MethodByName("Show")
values := make([]reflect.Value, 0)
methodByName.Call(values)
}
2.5 Judge
func judgeType() {
name := Name{
Name: "123"}
typeOf := reflect.TypeOf(name)
switch typeOf.Kind() {
case reflect.Slice:
fmt.Println(" section ")
case reflect.Array:
fmt.Println(" Array ")
case reflect.Struct:
fmt.Println(" Structure ")
}
// Determine the specific type
var ti interface{
} = &name
switch ti.(type) {
case *Name:
fmt.Printf("%+v\n", ti)
}
}
边栏推荐
- Introduction to DB2 SQL pl
- AFL fuzzy multithreading
- Stream生成的3张方式-Lambda
- 2021年全球十大模拟IC供应商:德州仪器稳居第一,Skyworks营收增幅最高
- Three ways generated by stream lambda
- Request header field xxxx is not allowed by Access-Control-Allow-Headers in preflight response问题
- 光储直柔配电系统浅析
- Adobe Premiere基础-不透明度(蒙版)(十一)
- 三部曲套路解bob活命问题
- 5. Golang泛型与反射
猜你喜欢

NaturalSpeech模型合成语音在CMOS测试中首次达到真人语音水平

muduo源码剖析——以三个切片浅析muduo库代码设计的严谨性、高效性与灵活性

How to set up salesmartly for Google Analytics tracking
![[CEPH] CEPH configuration source code analysis | common/config*](/img/d6/ba8d3ccc28d11e7fd9662b730fd998.jpg)
[CEPH] CEPH configuration source code analysis | common/config*

Adobe Premiere基础-不透明度(混合模式)(十二)

In the introductory study of data visualization, we should be alert to pitfalls and misunderstandings and grasp key nodes

Salesmartly | add a new channel slack to help you close the customer relationship

如何设置 SaleSmartly 以进行 Google Analytics(分析)跟踪

低碳数据中心建设思路及未来趋势

Adobe Premiere基础-时间重映射(十)
随机推荐
ACL2022 | bert2BERT:参数复用的高效预训练方法,显著降低超大模型的训练成本
Form form of the uniapp uview framework, input the verification mobile number and verification micro signal
leecode27,977-双指针法
AD18器件库导入简介
数字化转型怎样转?朝哪转?
作为程序员,对于底层原理真的有那么重要吗?
【存储】下一代分布式文件系统 研究
三部曲套路解bob活命问题
[QNX hypervisor 2.2 user manual] 3.2.3 ACPI table and FDT
[CEPH] CEPH configuration source code analysis | common/config*
Db2 SQL PL的动态SQL
数据的软删除—什么时候需要?又如何去实现?
一道题讲解动态规划的前世今生
阅读micropyton源码-添加C扩展类模块(4)
Huawei cloud Kunpeng devkit code migration practice
Research on next generation distributed file system
企业管理者的质疑,这么多年的信息化,我们的钱花哪去了?
afl-fuzz多线程
ETL的使用过程中遇到的坑(ETL中文乱码)
改变世界的开发者丨玩转“俄罗斯方块”的瑶光少年