Golang初级系列教程-结构体方法-Methods on structs
2016-01-14 15:56
656 查看
Golang初级系列教程-结构体方法-Methods on structs
比如现在想定义一个没有参数,并且返回
接下来,我们定义一个结构体叫做
让我们扩展之前写的结构体
许多面向对象语言,都有一个
上面代码中,调用
上面代码中,一个方法传值,另一个方法传递指针。通过
让我们继续对
你可能已经注意到,这种添加方法的方式非常灵活,那么是不是也可以对
但是如果你确实想实现这样的功能,那么我们可以利用前面学到的匿名字段。
下面的代码是前面
Golang一种神奇的语言,让我们一起进步
Methods on structs
上一篇文章已经介绍结构体中可以包含属性,同样结构体中可以有方法。方法的定义和普通函数定义相似,唯一的区别是方法需要attach to或者说
associated with(关联)一个结构体。
比如现在想定义一个没有参数,并且返回
int的普通函数,可能同下面代码类似
func my_func() int { //code }
接下来,我们定义一个结构体叫做
my_type,这时,将如上的函数关联到
my_type,那么
my_func就是
my_type的一个方法。
type my_type struct { } func (m my_type) my_func() int { //code }
让我们扩展之前写的结构体
Rectangle和
Area函数。这一次,
Area将只为
Rectangle服务,成为其一个方法。
package main import "fmt" type Rectangle struct { length, width int } func (r Rectangle) Area() int { return r.length * r.width } func main() { r1 := Rectangle{4, 3} fmt.Println("Rectangle is: ", r1) fmt.Println("Rectangle area is: ", r1.Area()) }
Rectangle is: {4 3} Rectangle area is: 12
许多面向对象语言,都有一个
this或者
self隐式的只想当前的实例,但在
Go中,并不存这样的概念。当定义方法是,都会给定一个变量名,如上面的例子中是 (
r Rectangle),在方法中,可以使用这个变量名。
上面代码中,调用
Area方法时,
Rectangle实例通过值传递。当然,也可以通过引用传递。对于方法而言,使用引用和值并没有太大的区别。
Go本身会自动识别,并且完成转换。
package main import "fmt" type Rectangle struct { length, width int } func (r Rectangle) Area_by_value() int { return r.length * r.width } func (r *Rectangle) Area_by_reference() int { return r.length * r.width } func main() { r1 := Rectangle{4, 3} fmt.Println("Rectangle is: ", r1) fmt.Println("Rectangle area is: ", r1.Area_by_value()) fmt.Println("Rectangle area is: ", r1.Area_by_reference()) fmt.Println("Rectangle area is: ", (&r1).Area_by_value()) fmt.Println("Rectangle area is: ", (&r1).Area_by_reference()) }
Rectangle is: {4 3} Rectangle area is: 12
Rectangle area is: 12
Rectangle area is: 12
Rectangle area is: 12
上面代码中,一个方法传值,另一个方法传递指针。通过
r1和
&r1分别调用两个方法,都能正确执行,源于
Go内部的处理机制。
让我们继续对
Rectangle添加一个方法
Perimeter——计算周长。
package main import "fmt" type Rectangle struct { length, width int } func (r Rectangle) Area() int { return r.length * r.width } func (r Rectangle) Perimeter() int { return 2* (r.length + r.width) } func main() { r1 := Rectangle{4, 3} fmt.Println("Rectangle is: ", r1) fmt.Println("Rectangle area is: ", r1.Area()) fmt.Println("Rectangle perimeter is: ", r1.Perimeter()) }
Rectangle is: {4 3} Rectangle area is: 12
Rectangle perimeter is: 14
你可能已经注意到,这种添加方法的方式非常灵活,那么是不是也可以对
int或者
time.Time添加方法呢?答案是否定的。由于,
Go允许和类型定义相同的包内进行方法声明。
func (t time.Time) first5Chars() string { return time.LocalTime().String()[0:5] }
cannot define new methods on non-local type time.Time
但是如果你确实想实现这样的功能,那么我们可以利用前面学到的匿名字段。
package main import "fmt" import "time" type myTime struct { time.Time //anonymous field } func (t myTime) first5Chars() string { return t.Time.String()[0:5] } func main() { m := myTime{*time.LocalTime()} //since time.LocalTime returns an address, we convert it to a value with * fmt.Println("Full time now:", m.String()) //calling existing String method on anonymous Time field fmt.Println("First 5 chars:", m.first5Chars()) //calling myTime.first5Chars }
Full time now: Tue Nov 10 23:00:00 UTC 2009 First 5 chars: Tue N
匿名字段的函数
深入分析上面的代码,想必你已经注意到,调用匿名字段方法的方式。由于time.Time是
myTime的匿名字段,我们可以如同访问
time.Time一样访问
myTime,即我们可以调用
myTime.String()。让我们通过更前面的一个例子更进一步说明。
下面的代码是前面
House和
Kitchen的例子。由于匿名字段,允许外围结构体直接访问内部结构体的字段,对于方法同样适用。当前,
Kitchen有一个方法
totalForksAndKnives(),所以
House可以直接访问
House.totalForksAndKnives()。
package main import "fmt" type Kitchen struct { numOfForks int numOfKnives int } func(k Kitchen) totalForksAndKnives() int { return k.numOfForks + k.numOfKnives } type House struct { Kitchen //anonymous field } func main() { h := House{Kitchen{4, 4}} //the kitchen has 4 forks and 4 knives fmt.Println("Sum of forks and knives in house: ", h.totalForksAndKnives()) //called on House even though the method is associated with Kitchen }
Sum of forks and knives in house: 8
Golang一种神奇的语言,让我们一起进步
相关文章推荐
- 第一个GO程序
- Django学习--9 多对一关系模型
- Golang初级系列教程-结构体匿名字段-Anonymous fields in structs
- Google 地图切片URL地址解析
- CodeForces 616D Longest k-Good Segment
- Google Chrome离线安装包下载 谷歌浏览器下载
- django 学习-7 模型数据操作
- Google工程师打造Remix OS系统 桌面版安卓下载
- 为什么category可以添加方法不能添加变量
- CF 615E Hexagons
- Uva11292--------------(The Dragon of Loowater)勇者斗恶龙 (排序后贪心)
- STL algorithm算法mov,move_backward(38)
- Mongoose的使用
- 协作神器:Leangoo
- golang 1.5/1.6/1.7 安装和配置
- 在Mac下用pip安装Django过程介绍
- Django开发博客(七)——markdown优化
- Goolge Map API 源码
- Golang的包管理、项目管理
- beego