先看一段代码
package app
import (
"github.com/gin-gonic/gin"
"github.com/EDDYCJY/go-gin-example/pkg/e"
)
type Gin struct {
C *gin.Context
}
func (g *Gin) Response(httpCode, errCode int, data interface{}) {
g.C.JSON(httpCode, gin.H{
"code": errCode,
"msg": e.GetMsg(errCode),
"data": data,
})
return
}
我发出疑问 正常的函数 不是 func 方法名 返回值,多出的(g *Gin)是啥呢?
查阅资料 问网友后发现 这是一种函数用法:Go 语言中同时有函数和方法
Go 语言中同时有函数和方法
概述:一个方法就是一个包含了接受的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。所有给定类型的方法属于该类型的方法集。
具体模式为
func (variable_name variable_data_type) function_name() [return_type]{
/* 函数体*/
}
实例
package main
import (
"fmt"
)
/* 定义结构体 */
type Circle struct {
radius float64
}
func main() {
var c1 Circle
c1.radius = 10.00
fmt.Println("圆的面积 = ", c1.getArea())
}
//该 method 属于 Circle 类型对象中的方法
func (c Circle) getArea() float64 {
//c.radius 即为 Circle 类型对象中的属性
return 3.14 * c.radius * c.radius
}
执行代码
圆的面积 = 314
看到这里 所以g.C.JSON()可以调用 因为
- *Gin 传递给 g
- *Gin 里有C
- C 里还有*gin.Context
- *gin.Context 有JSON() 方法
除此之外 go 函数还有两种用法 闭包和方法
闭包
概念:Go 语言支持匿名函数,可作为闭包。匿名函数是一个”内联”语句或表达式。匿名函数的优越性在于可以直接使用函数内的变量,不必申明。
具体例子
package main
import "fmt"
//函数 getSequence() 返回匿名函数 func() int
func getSequence() func() int {
i:=0
return func() int {
i+=1
return i
}
}
func main(){
/*nextNumber 为一个函数,函数 i 为 0 */
nextNumber := getSequence()
/* 调用 nextNumber 函数,i 变量自增 1 并返回 */
fmt.Println(nextNumber())
fmt.Println(nextNumber())
fmt.Println(nextNumber())
/* 创建新的函数 nextNumber1,并查看结果 */
nextNumber1 := getSequence()
fmt.Println(nextNumber1())
fmt.Println(nextNumber1())
}
执行结果 依次输出:1 2 3 1 2
函数作为实参
这个比较简单,直接代码
package main
import (
"fmt"
"math"
)
func main(){
/* 声明函数变量 */
getSquareRoot := func(x float64) float64 {
return math.Sqrt(x)
}
/* 使用函数 */
fmt.Println(getSquareRoot(9))// getSquareRoot(9) 成了Println的实参
}
直接输出 3