go语言的type func()用法

在go语言中,type可以定义任何自定义的类型

比如熟悉的:type dog struct{},type myInt int 等等

所以func也是可以作为类型自定义的,type myFunc func(int) int,意思是自定义了一个叫myFunc的函数类型,这个函数的签名必须符合输入为int,输出为int

已知,相同底层类型的变量之间是可以相互转换的,例如从一个取值范围小的int16转为取值范围大的int32

所以,自定义的 myInt 和 int 之间也是可以转换的

type myInt int

func main() {
    var a int
    a = 2
    b := myInt(a)
    fmt.Println(b)    // 2
}

同理,myFunc 也是可以将签名为 func(int) int 的函数转换成 myFunc 类型

type myFunc func(int) int


func sum10(num int) int {
    fmt.Println(num*10)
}


func main() {
    newFunc := myFunc(sum10)
}

此时newFunc是一个变量,变量类型为myFunc,值为sum10函数!!!

那么,这个变量有什么用?

回过头来想想,自定义的类型有什么用?有什么场景需要自己定义一个myInt出来?就是重载原来的int类型,并自定义新的方法

type myInt int

func (mi myInt) IsZero() bool {
    return mi == 0
}

func main() {
    var a myInt
    a = 0
    fmt.Println(a.IsZero())        // true
}

同理,自定义函数类型也可以自定义方法

type myFunc func(int) int

func (mf myfunc) sum(a,b int) int {
    c := a + b
    return mf(c)
}

一个自定义函数类型的变量拥有了一个sum函数,有什么实际用途?

重点来了,有什么用途?

举个例子

type myFunc func(int) int

func (f myFunc) sum (a, b int) int {
    res := a + b
    return f(res)
}

func sum10(num int) int {
    return num * 10
}

func sum100(num int) int {
    return num * 100
}

func handlerSum(handler myFunc, a, b int) int {
    res := handler.sum(a, b)
    fmt.Println(res)
    return res
}

func main() {
    newFunc1 := myFunc(sum10)
    newFunc2 := myFunc(sum100)

    handlerSum(newFunc1, 1, 1)    // 20
    handlerSum(newFunc2, 1, 1)    // 200
}

解释下,假如handlerSum是一种特殊的sum算法,但是又有一部分的计算是可以通过外部自定义函数来干预的,那么使用这种方式就很合适

再进一步,如何使得handlerSum函数更抽象化?我必须传递一个myFunc类型的变量参数进来吗?参数是一个interface呢,一个拥有sum方法的interface是不是更通用?

type sumable interface {
    sum(int, int) int
}

// myFunc继承sumable接口
type myFunc func(int) int

func (f myFunc) sum (a, b int) int {
    res := a + b
    return f(res)
}

func sum10(num int) int {
    return num * 10
}

func sum100(num int) int {
    return num * 100
}

// icansum结构体继承sumable接口
type icansum struct {
    name string
    res int
}

func (ics *icansum) sum(a, b int) int {
    ics.res = a + b
    return ics.res
}

// handler只要是继承了sumable接口的任何变量都行,我只需要你提供sum函数就好
func handlerSum(handler sumable, a, b int) int {
    res := handler.sum(a, b)
    fmt.Println(res)
    return res
}

func main() {
    newFunc1 := myFunc(sum10)
    newFunc2 := myFunc(sum100)

    handlerSum(newFunc1, 1, 1)    // 20
    handlerSum(newFunc2, 1, 1)    // 200

    ics := &icansum{"I can sum", 0}
    handlerSum(ics, 1, 1)         // 2
}

这样handlerSum接受的是一个只要实现了sum接口的变量就可以了,可以是一个struct变量,也可以是一个自定义函数类型变量,只要变量继承实现了sum函数即可,这样就可以更自由的干预(自定义)handlerSum函数需要的执行过程了

  • 20
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
在 Go 语言中,我们可以使用内置的“encoding/json”包来处理 JSON 数据。首先,我们需要定义一个结构体类型,该结构体的字段与 JSON 数据中的键名相对应。然后,我们可以使用 json.Unmarshal() 方法将 JSON 数据解析到这个结构体中,或者使用 json.Marshal() 方法将结构体转换为 JSON 数据。下面是一个简单的示例代码: ``` package main import ( "encoding/json" "fmt" ) type Person struct { Name string `json:"name"` Age int `json:"age"` Address string `json:"address,omitempty"` } func main() { jsonData := `{"name":"Alice","age":26,"address":"China"}` var p Person err := json.Unmarshal([]byte(jsonData), &p) if err != nil { fmt.Println("error:", err) } fmt.Println(p.Name) fmt.Println(p.Age) newJsonData, err := json.Marshal(p) if err != nil { fmt.Println("error:", err) } fmt.Println(string(newJsonData)) } ``` 这个代码定义了一个名为“Person”的结构体类型,它有三个字段:Name、Age 和 Address。其中,Name 和 Age 字段映射到 JSON 数据中的“name”和“age”键,而 Address 字段则映射到 JSON 数据中的“address”键。在main函数中,我们将一个 JSON 字符串解析为一个 Person 对象,然后打印出 Name 和 Age 字段的值,并将这个对象转换回 JSON 数据,并打印出来。注意,Address 字段有一个“omitempty”的标记,表示如果 Address 字段的值为空,则在序列化为 JSON 数据时会忽略这个字段。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值