函数 & 方法 & 接口

数据类型 Liemer_Lius 324℃

函数

函数定义了名称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 » 函数 & 方法 & 接口

喜欢 (1)

评论已关闭。