博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Golang教程:方法
阅读量:5243 次
发布时间:2019-06-14

本文共 3534 字,大约阅读时间需要 11 分钟。

什么是方法

一个方法只是一个函数,它有一个特殊的接收者(receiver)类型,该接收者放在 func 关键字和函数名之间。接收者可以是结构体类型或非结构体类型。可以在方法内部访问接收者。

通过下面的语法创建一个方法:

func (t Type) methodName(parameter list) {  }

上面的代码片段创建了一个名为 methodName 的方法,该方法有一个类型为 Type 的接收者。

例子

让我们编写一个简单的程序,它创建一个结构体类型的方法并调用它。

package mainimport (      "fmt")type Employee struct {      name     string    salary   int    currency string}/* displaySalary() method has Employee as the receiver type*/func (e Employee) displaySalary() {      fmt.Printf("Salary of %s is %s%d", e.name, e.currency, e.salary)}func main() {      emp1 := Employee {        name:     "Sam Adolf",        salary:   5000,        currency: "$",    }    emp1.displaySalary() //Calling displaySalary() method of Employee type}

上面程序的第 6 行,我们创建了 Employee 的一个名为 displaySalary 的方法。在 displaySalary() 方法内部可以访问它的接收者 e (类型为 Employee)。在第 17 行,我们使用接收者 e,并打印它的 namecurrency 以及 salary

在第26行,我们使用 emp1.displaySalary() 这样的语法来调用方法。

程序的输出为:Salary of Sam Adolf is $5000

为什么使用方法而不是函数?

上面的程序可以使用函数而不是方法重写如下

package mainimport (      "fmt")type Employee struct {      name     string    salary   int    currency string}/* displaySalary() method converted to function with Employee as parameter*/func displaySalary(e Employee) {      fmt.Printf("Salary of %s is %s%d", e.name, e.currency, e.salary)}func main() {      emp1 := Employee{        name:     "Sam Adolf",        salary:   5000,        currency: "$",    }    displaySalary(emp1)}

在上面的程序中,我们使用 displaySalary 函数替换了方法,并将 Employee 结构体作为参数传给它。该程序的输出与上面的程序输出一样:Salary of Sam Adolf is $5000

为什么使用方法而不是函数?

上面的程序可以使用函数而不是方法重写如下:

package mainimport (      "fmt")type Employee struct {      name     string    salary   int    currency string}/* displaySalary() method converted to function with Employee as parameter*/func displaySalary(e Employee) {      fmt.Printf("Salary of %s is %s%d", e.name, e.currency, e.salary)}func main() {      emp1 := Employee{        name:     "Sam Adolf",        salary:   5000,        currency: "$",    }    displaySalary(emp1)}

在上面的程序中,我们使用 displaySalary 函数替换了方法,并将 Employee 结构体作为参数传给它。该程序的输出与上面的程序输出一样:Salary of Sam Adolf is $5000

那么为什么我们可以用函数完成同样的工作,却还要使用方法呢?这里有几个原因,我们一个一个地看。

  • ,它不支持 class 类型。因此通过在一个类型上建立方法来实现与 class 相似的行为。
  • 同名方法可以定义在不同的类型上,但是 Go 不允许同名函数。假设我们有一个 Square 和 Circle 两个结构体。在 Square 和 Circle 上定义同名的方法是合法的,比如下面的程序:
package mainimport (      "fmt"    "math")type Rectangle struct {      length int    width  int}type Circle struct {      radius float64}func (r Rectangle) Area() int {      return r.length * r.width}func (c Circle) Area() float64 {      return math.Pi * c.radius * c.radius}func main() {      r := Rectangle{        length: 10,        width:  5,    }    fmt.Printf("Area of rectangle %d\n", r.Area())    c := Circle{        radius: 12,    }    fmt.Printf("Area of circle %f", c.Area())}

程序的输出为:

Area of rectangle 50  Area of circle 452.389342

定义非结构体类型的方法

现在我们定义的都是结构体类型的方法。同样可以定义非结构体类型的方法,不过这里需要注意一点。为了定义某个类型的方法,接收者类型的定义与方法的定义必须在同一个包中。目前为止,我们定义的结构体和相应的方法都是在main包中的,因此没有任何问题。

package mainfunc (a int) add(b int) {  }func main() {}

在上面的程序中,第3行我们试图添加一个方法 add 给内置类型 int。这是不允许的,因为定义方法 add 所在的包和定义类型 int 的包不是同一个包。这个程序将会报编译错误:cannot define new methods on non-local type int

使其工作的方法为定义内置类型的别名,然后以这个新类型为接收者创建方法。

package mainimport "fmt"type myInt intfunc (a myInt) add(b myInt) myInt {      return a + b}func main() {      num1 := myInt(5)    num2 := myInt(10)    sum := num1.add(num2)    fmt.Println("Sum is", sum)}

上面的程序中,第5行,我们创建了新的类型,一个 int 的别名 myInt。在第7行,我们定义了一个方法 add,以 myInt作为接收者。

程序的输出为: Sum is 15

转载于:https://www.cnblogs.com/liuzhongchao/p/9183746.html

你可能感兴趣的文章
如何设置映射网络驱动器的具体步骤和方法
查看>>
ASP.NET WebApi 基于OAuth2.0实现Token签名认证
查看>>
SendMail与Postfix的架构备忘
查看>>
paip.mysql 性能测试 报告 home right
查看>>
Atitit.跨平台预定义函数 魔术方法 魔术函数 钩子函数 api兼容性草案 v2 q216 java c# php js.docx...
查看>>
283. Move Zeroes把零放在最后面
查看>>
我的函数说明风格
查看>>
ssh 简介
查看>>
26.无向网邻接表类
查看>>
Visual Studio Code 打开.py代码报Linter pylint is not installed解决办法
查看>>
洛谷 p1352 没有上司的舞会 题解
查看>>
Python 数据类型
查看>>
Task 与 Activity
查看>>
Google Guava学习笔记——简介
查看>>
历时八年,HTML5 标准终于完工了
查看>>
17.树的子结构
查看>>
D - Mike and strings
查看>>
C++:多维数组的动态分配(new)和释放(delete)
查看>>
c#基础学习(0806)之抽象类实现多态
查看>>
S5PV210根文件系统的制作(一)
查看>>