跟着猫哥学Golang[12] - 结构体的方法
2015-11-23 15:19
495 查看
Golang 没有类,只有结构体。不过Golang可以在结构体类型上定义方法,其实就是配合结构体的函数。方法和之前讲过的函数是有些小区别的——对应的结构体信息(也叫“方法接受者”),出现在方法定义中。
猫哥语:有Golang特色的方法。
1. 结构体方法的定义格式:
func (var *Struct_Name) FuncName( var0, var1... ) return type { }
来看个最简单的例子:
2. 可以对任何type define的类型绑定方法
来看这个例子:
package main
import "fmt"
type myInteger int
func (i myInteger) Abs() int {
if i < 0 {
return int(-i)
}
return int(i)
}
func main() {
var inx myInteger
inx = -100
fmt.Println(inx.Abs())
}
# 输出:
100
3. 方法可以与命名类型或命名类型的指针关联。
刚刚看到的两个例子中的方法。一个是在*Rectangle指针类型上,而另一个在 myInteger 值类型上。
有两个原因需要使用指针接收者:
首先,避免在每个方法调用中拷贝值(如果值类型是大的结构体的话会更有效率);
其次,方法可以修改接收者指向的值。
来看下面这个对比的例子,就明白了。
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v *Vertex) Belarger(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func (v Vertex) Belarger1(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func (v *Vertex) Distance() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := &Vertex{3.0, 4.0}
fmt.Println("Original: ", v, v.Distance())
fmt.Println("----------------------------")
v.Belarger1(5.0)
fmt.Println("After no pointer method: ",v, v.Distance())
fmt.Println("----------------------------")
v.Belarger(5.0)
fmt.Println("After pointer method: ", v, v.Distance())
fmt.Println("----------------------------")
}
# 输出:
Original: &{3 4} 5
----------------------------
After no pointer method: &{3 4} 5
----------------------------
After pointer method: &{15 20} 25
Belarger用的指针的,所以结构体里的值改变了;与之对比的Belarger1用的类型的,没用指针,结构体里的值没有跟着变。
Golang 没有类,只有结构体。不过Golang可以在结构体类型上定义方法,其实就是配合结构体的函数。方法和之前讲过的函数是有些小区别的——对应的结构体信息(也叫“方法接受者”),出现在方法定义中。
猫哥语:有Golang特色的方法。
1. 结构体方法的定义格式:
func (var *Struct_Name) FuncName( var0, var1... ) return type { }
来看个最简单的例子:
package main import "fmt" type Rectangle struct { x, y float32 } func (v *Rectangle) Area() float32 { return v.x * v.y } func (v *Rectangle) Circle() float32 { return (v.x + v.y) * 2 } func main() { v := &Rectangle {3.5, 4.5} fmt.Println(v.Area()) fmt.Println(v.Circle()) } # 输出 15.75 16
2. 可以对任何type define的类型绑定方法
来看这个例子:
package main
import "fmt"
type myInteger int
func (i myInteger) Abs() int {
if i < 0 {
return int(-i)
}
return int(i)
}
func main() {
var inx myInteger
inx = -100
fmt.Println(inx.Abs())
}
# 输出:
100
3. 方法可以与命名类型或命名类型的指针关联。
刚刚看到的两个例子中的方法。一个是在*Rectangle指针类型上,而另一个在 myInteger 值类型上。
有两个原因需要使用指针接收者:
首先,避免在每个方法调用中拷贝值(如果值类型是大的结构体的话会更有效率);
其次,方法可以修改接收者指向的值。
来看下面这个对比的例子,就明白了。
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v *Vertex) Belarger(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func (v Vertex) Belarger1(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func (v *Vertex) Distance() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := &Vertex{3.0, 4.0}
fmt.Println("Original: ", v, v.Distance())
fmt.Println("----------------------------")
v.Belarger1(5.0)
fmt.Println("After no pointer method: ",v, v.Distance())
fmt.Println("----------------------------")
v.Belarger(5.0)
fmt.Println("After pointer method: ", v, v.Distance())
fmt.Println("----------------------------")
}
# 输出:
Original: &{3 4} 5
----------------------------
After no pointer method: &{3 4} 5
----------------------------
After pointer method: &{15 20} 25
Belarger用的指针的,所以结构体里的值改变了;与之对比的Belarger1用的类型的,没用指针,结构体里的值没有跟着变。
相关文章推荐
- Go 语言 Channel 实现原理精要
- Go语言将支持Android
- 注册表的组织结构
- Mootools 1.2教程 函数
- autoit InputBox 函数
- 文件遍历排序函数
- Oracle 函数大全[字符串函数,数学函数,日期函数]第1/4页
- ASP下经常用的字符串等函数参考资料
- PostgreSQL教程(五):函数和操作符详解(1)
- DOS批处理 函数定义与用法
- asp Chr 函数 数字转字母的方法
- Lua中的函数精讲笔记
- Lua中的闭合函数、非全局函数与函数的尾调用详解
- Lua中调用C++函数示例
- Lua实现split函数
- Lua常用时间函数使用实例
- Lua函数与字符串处理简明总结
- Lua学习笔记之表和函数
- Lua中实现sleep函数功能的4种方法
- Lua函数用法研究