golang Methods on structs
原文:http://golangtutorials.blogspot.com/2011/06/methods-on-structs.html
snmp 下载,有空学习一下!
https://sourceforge.net/projects/net-snmp/
--------------------------------------------------------------------------------------------------------
Methods on structs
We have learnt that structs can contain data. structs can also contain behavior in the form of methods. The definition of a method attached to or associated with a struct or any other type for that matter, is quite similar to a normal func definition, the only difference being that you need to additionally specify the type.
A normal function that we name my_func that takes no parameters and returns an
A function or method that we name my_func that takes no parameters and returns an
Let’s extend our earlier
Many object oriented languages have a concept of
In the above call to
In the above code, we have defined two similar functions, one which takes the
Just to extend the example, let’s do one more function that works on the same type. In the below example, we ‘attach’ a function to calculate the perimeter of the
You might be tempted now to see if you can attach methods and behavior to any type, say like an
However, if you absolutely need to extend the functionality, you can easily use what we learnt about anonymous fields and extend the functionality.
A normal function that we name my_func that takes no parameters and returns an
int
would be defined similar to that shown below.Partial code
func my_func() int { //code }
A function or method that we name my_func that takes no parameters and returns an
int
, but which is associated with a type we name my_type would be defined similar to that shown below.Partial code
type my_type struct { } func (m my_type) my_func() int { //code }
Let’s extend our earlier
Rectangle
struct to add an Area
function. This time we will define that the Area
function works explicitly with the Rectangle
type with func (r Rectangle) Area() int
.Full code
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
Rectangle area is: 12
Many object oriented languages have a concept of
this
or self
that implicitly refers to the current instance. Go has no such keyword. When defining a function or method associated with a type, it is given as a named variable - in this case (r Rectangle)
and then within the function the variable r
is used.In the above call to
Area
, the instance of Rectangle
is passed as a value. You could also pass it by reference. In calling the function, there would be no difference whether the instance that you call it with is a pointer or a value because Go will automatically do the conversion for you.Full code
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
Rectangle area is: 12
Rectangle area is: 12
Rectangle area is: 12
Rectangle area is: 12
In the above code, we have defined two similar functions, one which takes the
Rectangle
instance as a pointer and one that takes it by value. We have called each of the functions, via a value r1
and once as an address &r1
. The results however are all the same since Go performs appropriate conversions.Just to extend the example, let’s do one more function that works on the same type. In the below example, we ‘attach’ a function to calculate the perimeter of the
Rectangle
type.Full code
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
Rectangle area is: 12
Rectangle perimeter is: 14
You might be tempted now to see if you can attach methods and behavior to any type, say like an
int
or time.Time
- not possible. You will be able to add methods for a type only if the type is defined in the same package.Partial code
func (t time.Time) first5Chars() string { return time.LocalTime().String()[0:5] }
cannot define new methods on non-local type time.Time
However, if you absolutely need to extend the functionality, you can easily use what we learnt about anonymous fields and extend the functionality.
Full code
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 *
// m := myTime{time.Now()} 这行是对的!!!!!!!!!! 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
First 5 chars: Tue N
Methods on anonymous fields
There was another item that we slipped into the previous program - method calls on anonymous fields. Sincetime.Time
was an anonymous field within myTime
, we were able to refer to a method of Time
as if it were a method of myTime
. i.e. we were able to do myTime.String()
. Let’s do one program using an earlier example.In the following code we go back to our house where we have a
Kitchen
as an anonymous field in House
. As we learnt with member fields, we can also access methods of anonymous fields as if they belong directly to the composing type. So House
has an anonymous Kitchen
which in turn has a method totalForksAndKnives()
; so now House.totalForksAndKnives()
is a valid call.Full code
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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2018-10-10 【转】6 Reasons Why JavaScript’s Async/Await Blows Promises Away (Tutorial)
2017-10-10 【转】shell中的内建命令, 函数和外部命令
2017-10-10 clear out all variables without closing terminal
2017-10-10 linux中shell命令test用法和举例
2017-10-10 解决vim粘贴时格式混乱的问题
2017-10-10 scp的两种方式
2017-10-10 source 命令的用法,是在当前bash环境下执行脚本文件