go泛型实现方式遐想

anko · · 2169 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

### 为了绕开反射的慢性能和go无泛型以及接口断言的慢性能,下面提供一种方式给大伙,我想这会开拓大伙的一些思维,转发需注明原著连接,谢谢! ### 主要是利用了组合的原理来实现的,下面直接给出代码,欢迎大伙评论。 ``` package main import "fmt" type Person struct { name string age int } type Animal struct { name string age int } //如果无泛型,我们需要下面这些累赘 //func (p Person) getName() string { // return p.name //} // //func (p Person) getAge() int { // return p.age //} // //func (a Animal) getName() string { // return a.name //} // //func (a Animal) getAge() int { // return a.age //} //下面是泛型,我们注释掉上面的几个方法 type Biological struct { _type string *Person *Animal } func (b Biological) getName() (name string) { switch b._type { //针对不同的类型做不同的事情 case "Person": name= b.Person.name case "Animal": name= b.Animal.name } return } func (b Biological) getAge() (age int) { switch b._type { //针对不同的类型做不同的事情 case "Person": age= b.Person.age case "Animal": age= b.Animal.age } return } //下面是接收泛型的处理函数 func testFun(b *Biological) { fmt.Println(b.getName()) fmt.Println(b.getAge()) } //下面是将具体的类型转成泛型类型实例的函数 func newGeneric(s string,p *Person,a *Animal) *Biological { return &Biological{ _type: s, Person: p, Animal: a, } } func main() { var p = Person{ name: "ppp", age: 10, } testFun(newGeneric("Person",&p,nil)) fmt.Println("--------------") var a = Animal{ name: "AAA", age: 20, } testFun(newGeneric("Animal",nil,&a)) } ``` ### 下面给出代码截图方便查看: ![image.png](https://static.studygolang.com/200408/a5b80639f3e3486b5bb47f6da89258de.png) ![image.png](https://static.studygolang.com/200408/549a0886ad3298ccd84c74467210107f.png) ![image.png](https://static.studygolang.com/200408/c719d2ac77875a3b13a895c91ed61a16.png) ### 这个应该是比反射的性能要好很多,特别是在并发函数里面,我们应该尽量避免使用反射或者 go库中使用到反射的函数! ### 为了再说明组合的好处,我们再举个例子如下: ``` package main import "fmt" type T struct { *string *int } //如果不建立泛型则需要像下面这样写,挺累赘的写法! //func return_string(s string) string { // return s //} //func return_int(i int) int { // return i //} func echo(arg T) T { return arg } func doubleStrOrInt(arg T) T { switch arg.int { case nil: //为string s := *arg.string s += s arg.string = &s default: //为int i := (*arg.int) * 2 arg.int = &i } return arg } func main() { s := "a"//基本类型 arg := T{string: &s}//泛型 str := echo(arg).string//调用接收泛型的函数且回去结果 fmt.Println(*str) ii := 1 arg1 := T{int: &ii} i := echo(arg1).int fmt.Println(*i) //------------ str = doubleStrOrInt(arg).string fmt.Println(*str) i = doubleStrOrInt(arg1).int fmt.Println(*i) } ``` ### 代码截图如下: ![image.png](https://static.studygolang.com/200408/64f939f1d21e0b17f0341a5dcf5631c0.png) ![image.png](https://static.studygolang.com/200408/4e229440b12ac17333aadfcbd32de2c1.png) ### 为了让读者意识到性能问题,我给出下面的测试: ``` //代码1 package main import ( "fmt" "sync" "time" ) func doubleStrOrInt(arg interface{}) interface{} { switch s := arg.(type) { case string: //为string s += s arg = s case int: //为int i := s * 2 arg = i } return arg } func main() { start := time.Now() s := "a" //基本类型 ii := 1 var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() //故意循环100000次 for k := 0; k < 100000; k++ { _ = doubleStrOrInt(s) //fmt.Println(str) _ = doubleStrOrInt(ii) //fmt.Println(i) } }() wg.Wait() end := time.Now() fmt.Println("耗时:", end.Sub(start)) } ``` ### 截图: ![image.png](https://static.studygolang.com/200408/f0b319feb83ad365a4e13fc08c060d29.png) ``` //代码2 package main import ( "fmt" "sync" "time" ) type T struct { *string *int } func doubleStrOrInt(arg T) T { switch arg.int { case nil: //为string s := *arg.string s += s arg.string = &s default: //为int i := (*arg.int) * 2 arg.int = &i } return arg } func main() { start := time.Now() s := "a" //基本类型 arg := T{string: &s} //泛型 ii := 1 arg1 := T{int: &ii} var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() //故意循环100000次 for k := 0; k < 100000; k++ { _ = doubleStrOrInt(arg).string //fmt.Println(*str) _ = doubleStrOrInt(arg1).int //fmt.Println(*i) } }() wg.Wait() end := time.Now() fmt.Println("耗时:", end.Sub(start)) } ``` ### 代码截图: ![image.png](https://static.studygolang.com/200408/b913f5f73536b7c3230419131ebba0db.png) ![image.png](https://static.studygolang.com/200408/d7fc6b2179865631648145c81759925d.png) ### 下面是上面2段代码的执行结果: ## 采用反射与断言的结果是: ## 耗时: 22.4633ms ## 而不采用反射,自定义类似泛型的结构体的执行结果则是: ## 耗时: 6.8349ms

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2169 次点击  
加入收藏 微博
2 回复  |  直到 2020-04-08 19:02:16
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传