Go教程定义方法

Posted 玖五二七

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go教程定义方法相关的知识,希望对你有一定的参考价值。

在Golang中不支持重载.不支持类,但是支持自定义方法

方法定义和函数定义很像,它们实际上只有一点不同,就是在函数的前面增加一个额外的叫做接收器的参数名称和类型即可

type MyType string
// m 接收器参数名称 Mytype 接收器参数类型
func (m MyType) foo(n int) 
  fmt.Println("from ",m, " get n", n)

和任何其他函数一样,需要提供一个接收器参数的名称,后面跟上其类型

为了调用你定义的方法,输入你要调用的方法的值,一个点和要调用的方法名称,跟一对().这里你调用的方法的值被称为方法接收器

// value是方法接收器
// foo是方法名
value := MyTpe("my type value")
value.foo(5)

调用方法和方法定义的相似之处在于,方法接收器都在开头.

方法定义中的接收器参数的名称并不关键,重要的是它的类型,你定义的方法与此类型的值都关联.

下面的代码中.我们定义一个名为MyType的类型,使用string作为基础类型.然后我们定义一个名为foo的方法.由于foo有一个MyType类型的接收器参数.我们可以使用任何MyType的值来调用foo方法,我们可以认为foo被定义在MyType上的

这里创建了2个不同的MyType值,然后分别调用它们的foo方法

method/a.go

package method

import "fmt"

type MyType string

// m MyType接收器
// n 是方法函数的参数
func (m MyType) foo(n int) 
  fmt.Println("from ", m, "  foo ", n)


func Test() 
  value := MyType("hello")
  value.foo(4)

  value1 := MyType("world")
  value1.foo(5)


main.go

package main

import (
  "fmt"
  "lesson2/method"
)

func main() 
  method.Test()


结果如下

from  hello   foo  4
from  world   foo  5

接收器是另一个参数

接收器参数的类型是与之 联系的方法的类型.除此以外,接收器在Go中没有什么特殊的.你可以在方法块中访问它的内容,和在其他的函数参数一样.

Go使用接收器参数来代替其他语言中的self或this

方法就像一个函数

方法除了它们在接收器上被调用外,其他与任何函数完全相同.

就像其他函数一样,你可以在方法名称的括号中定义额外的参数.参数变量与接收器参数一样,可以被方法块访问.当你调用方法时,你将需要为每个参数提供值.

与其它函数一样,你可以为方法的声明一个或多个返回值,返回值将在函数被调用时返回.

func (m MyType) withRetrun() (int, string) 
  return 0, "hello"

func Test() 
  value2 := MyType("i am 3")
  r1, r2 := value2.withRetrun()
  fmt.Println("return is ", r1, r2)  // 输出 return is  0 hello


同函数的导出规则一样,当方法名称以大写字母开头,则认为是可以被导出的.如果是小写字母开头,则认为是不被导出的.如果你想要在当前包以外使用你的方法,确保它的名称以大写字母开头.

指针类型的接收器参数

在函数中我们的AutoAdd函数没使用指针前它的值没法在函数外部生效.我们是使用了指针以后这个AutoAdd传入的参数才增加的.

之前提到过接收器参数与普通参数没有区别.和其他函数一样,接收器参数也接收一个接收器的拷贝值.如果你使用的方法来修改接收器.你修改的就是拷贝,而不是原始值.

解决方案是以指针来做接收器参数.这个和其他参数的方法相同.放置指针运算符*在接收器类型的前面来标识它是指针类型.

方法的内部会修改指针指向的值.我们不需要修改方法的调用.当你用一个非指针的变量调用一个需要指针的接收器的方法的时候.Go会自动为你将非指针类型转成指针类型.同样一个指针类型的调用也会自动被转换为非指针类型.

func (m *MyType) fooPointer(n int) 
  fmt.Println("from pointer call", *m, "  foo ", n)

func (m MyType) foo(n int) 
  fmt.Println("from ", m, "  foo ", n)


func Test() 
  value := MyType("hello") // 创建一个MyType类型
  p := &value              // 声明一个指针
  value.foo(4)             // 值调用方法
  value.fooPointer(4)      // 值调用 方法
  p.foo(4)                 // 指针调用方法
  p.fooPointer(4)          // 指针调用方法

以上的代码都 是正确的.名称为foo的方法接收一个值类型的接收器,但是我们同时使用了值类型和指针类型,因为如果需要,Go会自动的转换.名为fooPointer的方法接收一个指针类型的接收器.但我们使用了值类型和指针类型调用了它,Go会自动转换

为了调用需要接收器指针的方法,你需要显示获取这个值类型的指针

你只能获取保存在变量中的指针.如果你尝试获取没有保存在变量中的值的地址,会得到一个错误:

&MyType(“a value”)

同样的限制也存在于使用接收器指针调用方法时.Go无法将值类型转换为指针类型,除非你将接收器的值保存在变量中.如果 你尝试在值类型上调用 方法.go也不会转换为指针 ,你会得到一个同样的错误.

正确的做法是显式的创建指针,让Go能得到指针的值.

以上是关于Go教程定义方法的主要内容,如果未能解决你的问题,请参考以下文章

Go教程定义方法

Go 系列教程 —— 17. 方法

go 入门教程变量

Go语法的基本使用

Go语言学习——结构体构造函数方法和接收者给自定义类型添加方法

Go语言值接收者方法和指针接收者方法