函数
函数定义了名称name,传入参数(parameter-list),通过函数体(body)的处理,返回结果(result-list),传入参数和返回结果都可以多个
func name(parameter-list) (result-list) { body }
方法
方法的声名和函数类似,只是在函数名字前面加了一个参数,这个参数把方法绑定到该类型上。
func (defined-type) name(parameter-list) (result-list) { body }
一个简单和例子说明说明一下两者的不同:
package main
import (
"fmt"
"math"
)
type Point struct{ X, Y float64 }
// 普通函数
func Distance(p, q Point) float64 {
return math.Hypot(q.X-p.X, q.Y-p.Y)
}
// Point类型的方法
func (p Point) Distance(q Point) float64 {
return math.Hypot(q.X-p.X, q.Y-p.Y)
}
type Path []Point
func (path Path) Distance() float64 {
sum := 0.0
for i := range path {
fmt.Println(i, path[i])
if i > 0 {
sum += path[i-1].Distance(path[i]) // 调用Point类型的方法
}
}
return sum
}
func main() {
a := Point{1, 2}
b := Point{4, 6}
perim := Path{
{1, 1},
{5, 1},
{5, 4},
{1, 1},
}
fmt.Println("函数调用:", Distance(a, b)) // 函数调用
fmt.Println("方法调用:", a.Distance(b)) // 单次Point方法调用, 计算线段的长
fmt.Println("周长:", perim.Distance()) // 多次Point方法调用, 计算周长
}
# ./main.exe
函数调用: 5
方法调用: 5
0 {1 1} // 0 < 1, 略过
1 {5 1} // 计算{5, 1}.Distance({1, 1})的长度后sum+=
2 {5 4} // 计算{5, 4}.Distance({5, 1})的长度后sum+=
3 {1 1} // 计算{1, 1}.Distance({5, 4})的长度后sum+=
周长: 12
这里的两个Distance不冲突: 一个是包级别的函数(geometry.Distance); 一个是类型Point的方法(Point.Distance)
包外引用的时候,函数需要带包的名称,而方法不需要。
接口
接口类型是对其它类型的概括与抽象。Go语言的接口是隐式实现的,即:具体的类型无需声明它实现了哪些接口,只需提供所需的方法即可。如此,无需修改已有类型的实现,就可以添加新的接口,对于不能修改的包类型,这点非常有用。
具体类型和接口类型的区别:
- 具体类型:它的数据有精确的布局,以及基于这个精确布局的内部操作。
- 接口类型:它是一种抽象的类型,并没有暴露出数据的布局、内部结构和基本操作,而是仅仅提供了一些方法。接口类型不能知道它是什么,只知道它可以做什么【提供了哪些方法】。
package io
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
type Closer interface {
Close() error
}
// 嵌入式接口-1: 用两个封装好的接口
type ReadWriter interface {
Reader
Writer
}
或
// 嵌入式接口-1: 用混合或者原始方法的接口
type ReadWriter interface {
Read(p []byte) (n int, err error)
Writer
}
type ReadWriteCloser interface {
Reader
Writer
closer
}
嵌入式接口可以直接调用,不用写出所有的方法。如:io.ReadWriter
转载请注明:liutianfeng.com » 函数 & 方法 & 接口