### 为了绕开反射的慢性能和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
折中一下,没法,性能的话肯定比定义接口高,你测试下就知道了,代码偏复杂点也是无奈之举,但是,我的目的是提高代码性能,抛开代码复杂这个缺点来说,这种方式确实值得参考
#2