首先大家知道golang是没有JAVA的泛型函数或者C++的模板函数这种语法的,今天学到了一种很有用的类似泛型操作的语法,拿来和大家分享
以大家喜闻乐见的Add函数来说明,目的是来实现一个泛型的Add函数
先写了三个ADD函数
package main
import (
"fmt"
)
func Add1(a, b int) int {
return a + b
}
func Add2(a, b float32) float32 {
return a + b
}
func Add3(a, b string) string {
return a + b
}
func main() {
a1 := Add1(1, 2)
a2 := Add2(1.33, 6.82)
a3 := Add3("hello ", "world")
fmt.Println("a1 =", a1, "a2 =", a2, "a3 =", a3)
}
在把三个ADD函数统一起来前,先学习一个简单的Interface{}的用法,注意int,int32,int64在setvalue的泛型判断中是不同的类型
package main
import (
"fmt"
)
func SetValue(ret interface{}) {
switch data := ret.(type) {
case *float32:
*data = 3.14
case *int:
*data = 23333
case *int32:
*data = 32
case *int64:
*data = 64
default:
fmt.Println("unknow type")
}
}
func main() {
var a1 int
var a2 int32
var a3 float32
var a4 int64
SetValue(&a1)
SetValue(&a2)
SetValue(&a3)
SetValue(&a4)
fmt.Println("a1 =", a1, "a2 =", a2, "a3 =", a3, "a4 =", a4)
}
相信到这里大部分同学都明白了,我们是要通过switch data:=input.(type)这样的类型判断来实现所谓的泛型,先按照最常规的
伪代码:Add(a,b){return a+b} 来实现
package main
import (
"fmt"
)
func main() {
a1 := Add1(1, 2)
a2 := Add2(1.33, 6.82)
a3 := Add3("hello ", "world")
fmt.Println("a1 =", a1, "a2 =", a2, "a3 =", a3)
b1 := GeneralAdd0(3, 5)
switch data := b1.(type) {
case int:
fmt.Println("b1=", data)
}
b2 := GeneralAdd0(1.33, 6.82)
switch data := b2.(type) {
case float64:
fmt.Println("b2=", data)
}
b3 := GeneralAdd0("hello ", "add0")
switch data := b3.(type) {
case string:
fmt.Println("b3=", data)
}
fmt.Println("b1 =", b1, "b2 =", b2, "b3 =", b3)
}
func Add1(a, b int) int {
return a + b
}
func Add2(a, b float32) float32 {
return a + b
}
func Add3(a, b string) string {
return a + b
}
func GeneralAdd0(a, b interface{}) interface{} {
switch data := b.(type) {
case float32:
switch ta := a.(type) {
case float32:
data = data + ta
return data
}
case float64:
switch ta := a.(type) {
case float64:
data = data + ta
return data
}
case int:
switch ta := a.(type) {
case int:
data = data + ta
return data
}
case string:
switch ta := a.(type) {
case string:
data = data + ta
return data
}
default:
fmt.Println("unknow type")
return nil
}
return nil
}
ps:这里b2其实是个float64类型
也可以传指针
package main
import (
"fmt"
)
func main() {
a1 := Add1(1, 2)
a2 := Add2(1.33, 6.82)
a3 := Add3("hello ", "world")
fmt.Println("a1 =", a1, "a2 =", a2, "a3 =", a3)
b1 := GeneralAdd0(3, 5)
switch data := b1.(type) {
case int:
fmt.Println("b1=", data)
}
b2 := GeneralAdd0(1.33, 6.82)
switch data := b2.(type) {
case float64:
fmt.Println("b2=", data)
}
b3 := GeneralAdd0("hello ", "add0")
switch data := b3.(type) {
case string:
fmt.Println("b3=", data)
}
fmt.Println("b1 =", b1, "b2 =", b2, "b3 =", b3)
var c1, cret1 int = 10, 42
GeneralAdd1(&c1, &cret1)
var c2, cret2 float32 = 5.11, 6.22
GeneralAdd1(&c2, &cret2)
var c3, cret3 string = "add1", "I am "
GeneralAdd1(&c3, &cret3)
fmt.Println("cret1 =", cret1, "cret2 =", cret2, "cret3 =", cret3)
}
func Add1(a, b int) int {
return a + b
}
func Add2(a, b float32) float32 {
return a + b
}
func Add3(a, b string) string {
return a + b
}
func GeneralAdd0(a, b interface{}) interface{} {
switch data := b.(type) {
case float32:
switch ta := a.(type) {
case float32:
data = data + ta
return data
}
case float64:
switch ta := a.(type) {
case float64:
data = data + ta
return data
}
case int:
switch ta := a.(type) {
case int:
data = data + ta
return data
}
case string:
switch ta := a.(type) {
case string:
data = data + ta
return data
}
default:
fmt.Println("unknow type")
return nil
}
return nil
}
func GeneralAdd1(a, ret interface{}) {
switch data := ret.(type) {
case *float32:
switch ta := a.(type) {
case *float32:
*data = *data + *ta
}
case *int:
switch ta := a.(type) {
case *int:
*data = *data + *ta
}
case *string:
switch ta := a.(type) {
case *string:
*data = *data + *ta
}
default:
fmt.Println("unknow type")
}
}
看到这里有没有想到一个问题,如果我的add函数是 伪代码:add(a,b,c){return a+b+c},难道我要switch case嵌套3次?这样的代码看着也太难受了
因此自定义的数据类型也是可以判断的哦
package main
import (
"fmt"
)
func main() {
a1 := Add1(1, 2)
a2 := Add2(1.33, 6.82)
a3 := Add3("hello ", "world")
fmt.Println("a1 =", a1, "a2 =", a2, "a3 =", a3)
b1 := GeneralAdd0(3, 5)
switch data := b1.(type) {
case int:
fmt.Println("b1=", data)
}
b2 := GeneralAdd0(1.33, 6.82)
switch data := b2.(type) {
case float64:
fmt.Println("b2=", data)
}
b3 := GeneralAdd0("hello ", "add0")
switch data := b3.(type) {
case string:
fmt.Println("b3=", data)
}
fmt.Println("b1 =", b1, "b2 =", b2, "b3 =", b3)
var c1, cret1 int = 10, 42
GeneralAdd1(&c1, &cret1)
var c2, cret2 float32 = 5.11, 6.22
GeneralAdd1(&c2, &cret2)
var c3, cret3 string = "add1", "I am "
GeneralAdd1(&c3, &cret3)
fmt.Println("cret1 =", cret1, "cret2 =", cret2, "cret3 =", cret3)
d1 := IntStruct{a: 9, b: 45, ret: 0}
GeneralAdd2(&d1)
d2 := Float32Struct{a: 4.77, b: 7.99, ret: 0.0}
GeneralAdd2(&d2)
d3 := StringStruct{a: "I am", b: "stringstruct", ret: ""}
GeneralAdd2(&d3)
fmt.Println("d1 =", d1.ret, "d2 =", d2.ret, "d3 =", d3.ret)
}
func Add1(a, b int) int {
return a + b
}
func Add2(a, b float32) float32 {
return a + b
}
func Add3(a, b string) string {
return a + b
}
func GeneralAdd0(a, b interface{}) interface{} {
switch data := b.(type) {
case float32:
switch ta := a.(type) {
case float32:
data = data + ta
return data
}
case float64:
switch ta := a.(type) {
case float64:
data = data + ta
return data
}
case int:
switch ta := a.(type) {
case int:
data = data + ta
return data
}
case string:
switch ta := a.(type) {
case string:
data = data + ta
return data
}
default:
fmt.Println("unknow type")
return nil
}
return nil
}
func GeneralAdd1(a, ret interface{}) {
switch data := ret.(type) {
case *float32:
switch ta := a.(type) {
case *float32:
*data = *data + *ta
}
case *int:
switch ta := a.(type) {
case *int:
*data = *data + *ta
}
case *string:
switch ta := a.(type) {
case *string:
*data = *data + *ta
}
default:
fmt.Println("unknow type")
}
}
type Float32Struct struct {
a float32
b float32
ret float32
}
type IntStruct struct {
a int
b int
ret int
}
type StringStruct struct {
a string
b string
ret string
}
func GeneralAdd2(ret interface{}) {
switch data := ret.(type) {
case *Float32Struct:
data.ret = data.a + data.b
case *IntStruct:
data.ret = data.a + data.b
case *StringStruct:
data.ret = data.a + data.b
default:
fmt.Println("unknow type")
}
}