Go语言中的结构体方法(非常详细)
传统面向对象语言的方法是定义在类中,而结构体的方法是定义在结构体之外的。通过将结构体和结构体方法分离,Go 语言的代码更加灵活。
和函数一样,结构体方法也使用 func 关键字定义。结构体方法和函数的最大区别是结构体方法需要在func关键字和方法名之间使用小括号声明一个变量作为方法的接收者。
根据变量的类型,结构体的方法分为两种形式:值接收者方法和指针接收者方法,下面分别进行介绍。
结构体方法只能由创建的结构体实例化变量进行调用。代码如下:
定义指针接收者方法的语法格式如下:
例如,修改前面的示例代码,在 profile 结构体中添加两个成员,在定义结构体方法时声明结构体方法的指针接收者,代码如下:
无论结构体方法采用值接收者还是指针接收者,结构体方法的调用方式都是一样的。
【实例】计算商品总价。定义表示商品信息的结构体,包括商品名称、商品单价和商品数量,分别通过结构体方法初始化结构体、获取商品信息和计算商品总价。代码如下:
和函数一样,结构体方法也使用 func 关键字定义。结构体方法和函数的最大区别是结构体方法需要在func关键字和方法名之间使用小括号声明一个变量作为方法的接收者。
根据变量的类型,结构体的方法分为两种形式:值接收者方法和指针接收者方法,下面分别进行介绍。
Go语言值接收者方法
定义值接收者方法的语法格式如下:func (变量 结构体名称) 方法名([参数 1, 参数 2, ...]) (返回类型) { 方法体 return }在上述语法格式中,结构体名称前的变量表示定义的结构体实例。参数列表和返回类型可以为空。在返回类型为空时,可以省略 return 语句。
结构体方法只能由创建的结构体实例化变量进行调用。代码如下:
package main import ( "fmt" "strconv" ) //定义结构体 type profile struct { name string age int } //定义结构体方法 func (p profile) get_info(subject string, score int) string { info := "姓名:" + p.name + "\n年龄:" + strconv.Itoa(p.age) info += "\n考试科目:" + subject + "\n考试分数:" + strconv.Itoa(score) return info } func main() { //实例化结构体 p := profile{name: "张三", age: 20} //调用结构体方法 result := p.get_info("综合知识", 76) fmt.Print(result) }运行结果如下:
姓名:张三
年龄:20
考试科目:综合知识
考试分数:76
Go语言指针接收者方法
在某些情况下,要使用指针类型的变量作为方法的接收者。一种是在调用方法时需要修改变量值,还有一种是结构体成员较多,占用内存较大。定义指针接收者方法的语法格式如下:
func (变量 *结构体名称) 方法名([参数1, 参数2,…]) (返回类型) { 方法体 return }
例如,修改前面的示例代码,在 profile 结构体中添加两个成员,在定义结构体方法时声明结构体方法的指针接收者,代码如下:
package main import ( "fmt" "strconv" ) //定义结构体 type profile struct { name string age int interest []string evaluate string } //定义指针接收者方法 func (p *profile) get_info(subject string, score int) string { info := "姓名:" + p.name + "\n年龄:" + strconv.Itoa(p.age) var hobby string for _, v := range p.interest { hobby += v + " " } info += "\n兴趣爱好:" + hobby + "\n自我评价:" + p.evaluate info += "\n考试科目:" + subject + "\n考试分数:" + strconv.Itoa(score) return info } func main() { //实例化结构体 p := &profile{ name: "张三", age: 20, interest: []string{"看电影", "弹琴", "唱歌"}, evaluate: "谦虚谨慎,自信乐观", } //调用结构体方法 result := p.get_info("综合知识", 76) fmt.Printf(result) }运行结果如下:
姓名:张三
年龄:20
兴趣爱好:看电影 弹琴 唱歌
自我评价:谦虚谨慎,自信乐观
考试科目:综合知识
考试分数:76
无论结构体方法采用值接收者还是指针接收者,结构体方法的调用方式都是一样的。
【实例】计算商品总价。定义表示商品信息的结构体,包括商品名称、商品单价和商品数量,分别通过结构体方法初始化结构体、获取商品信息和计算商品总价。代码如下:
package main import ( "fmt" "strconv" ) //定义结构体 type goods struct { name []string price []int num []int } //定义结构体方法,获取商品信息 func (g *goods) show() string { var info string for k, v := range g.name { info += "商品名称:" + v info += " 商品单价:" + strconv.Itoa(g.price[k]) + "元" info += " 商品数量:" + strconv.Itoa(g.num[k]) + "\n" } return info } //定义结构体方法,计算商品总价 func (g *goods) count() int { var total int //商品总价 for k, v := range g.price { total += v * g.num[k] } return total } //定义结构体方法 func (g *goods) init(name []string, price []int, num []int) { //初始化结构体成员 g.name = name g.price = price g.num = num } func main() { //实例化结构体 g := &goods{} //调用结构体方法,初始化结构体成员值 g.init([]string{"品牌手机", "品牌计算机"}, []int{1699, 2399}, []int{2, 3}) info := g.show() //调用结构体方法,获取商品信息 result := g.count() //调用结构体方法,计算商品总价 fmt.Print(info) fmt.Printf("商品总价:%v 元\n", result) }运行结果如下:
商品名称:品牌手机 商品单价:1699元 商品数量:2
商品名称:品牌计算机 商品单价:2399元 商品数量:3
商品总价:10595元