go语言方法-学习笔记

方法

什么是方法

方法其实和函数一样,只不过方法指定了接收者。

接收者可以是明明类型或者是结构体类型中的值或者指针。

语法

语法:

​ func (接收者) 方法名(参数)(返回值){

​ }

接收者类型可以是(几乎)任何类型,不仅仅是结构体类型:任何类型都可以有方法,甚至可以是函数类型,可以是 int、bool、string 或数组的别名类型。但是接收者不能是一个接口类型,因为接口是一个抽象定义,但是方法却是具体实现;如果这样做会引发一个编译错误:invalid receiver type…

最后接收者不能是一个指针类型,但是它可以是任何其他允许类型的指针。

因为方法是函数,所以不允许方法重载,即对于一个类型只能有一个给定名称的方法。但是如果基于接收者类型,是有重载的:具有同样名字的方法可以在 2 个或多个不同的接收者类型上存在,比如在同一个包里这么做是允许的:

func (a *denseMatrix) Add(b Matrix) Matrix
func (a *sparseMatrix) Add(b Matrix) Matrix

下面举个小例子:

func main() {
	p := People{Name: "zhang san", Age: 99, Address: "China"}
	p.sayHello() //hello, zhang san
}

type People struct {
	Name    string
	Age     int
	Address string
}

func (p People) sayHello() {
	fmt.Println("hello, ", p.Name)
}

与函数对比

方法与函数的意义实际上是不一样的,函数只是一段功能性代码,可以直接调用。

而方法是某个类别的行为,需要指定接受者来进行调用。

还有一点不同就是,方法的名字可以相同,但指定接收者必须是不一样的。

变量作用域

go语言的变量可以在三个地方声明:

  • 函数内定义,局部变量
  • 函数外定义,全局变量
  • 函数定义的变量,形式参数

局部变量

在函数体内声明的变量称之为局部变量,他们的作用域仅仅在函数体内,参数与返回值都是局部变量。

全局变量

函数体外都变量称之为全局变量,首字母大写的全局变量可以在整个包甚至外部的包使用。

继承

go语言实际上没有太过明显的面向对象思想,但是我们可以模拟继承。

  1. 模拟继承:is - a

    type A struct{

    ​ field

    }

    type B struct{

    ​ A // 匿名字段

    }

  2. 模拟聚合关系:has - a

    t ype C struct{

    ​ c C

    }

子类打印父类方法:

func main() {
	p := People{Name: "zhang san", Age: 99, Address: "China"}
	s := Student{p, "qinghua"}
	s.printInfo() //{zhang san 99 China}
}

type People struct {
	Name    string
	Age     int
	Address string
}

type Student struct {
	People
	school string
}

func (p People) printInfo() {
	fmt.Println(p)
}

方法的命名

在编程中一些基本操作会一遍又一遍的出现,比如打开(Open)、关闭(Close)、读(Read)、写(Write)、排序(Sort)等等,并且它们都有一个大致的意思:打开(Open)可以作用于一个文件、一个网络连接、一个数据库连接等等。具体的实现可能千差万别,但是基本的概念是一致的。在 Go 语言中,通过使用接口(参考 第 11 章),标准库广泛的应用了这些规则,在标准库中这些通用方法都有一致的名字,比如 Open()Read()Write()等。想写规范的 Go 程序,就应该遵守这些约定,给方法合适的名字和签名,就像那些通用方法那样。这样做会使 Go 开发的软件更加具有一致性和可读性。比如:如果需要一个 convert-to-string 方法,应该命名为 String(),而不是 ToString()

多重继承

在如 C++、Java、C# 和 Ruby 这样的面向对象语言中,方法在类的上下文中被定义和继承:在一个对象上调用方法时,运行时会检测类以及它的超类中是否有此方法的定义,如果没有会导致异常发生。

在 Go 语言中,这样的继承层次是完全没必要的:如果方法在此类型定义了,就可以调用它,和其他类型上是否存在这个方法没有关系。在这个意义上,Go 具有更大的灵活性。

posted on 2020-03-07 22:38  长方形  阅读(327)  评论(0编辑  收藏  举报

导航