Go 方法

什么是方法:

方法其实就是一个函数,在func这个关键字和方法名中间加入了一个特殊的接收器类型,接收器可以是结构体类型或者是非结构体类型,接收器是可以在方法的内部访问的。

下面就是创建一个方法的语法:

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

上面的代码片段创建了一个接收器类型为Type的方法 methodName

示例:

在Employee结构体类型上创建一个displaySalary方法,displaySalart()方法在方法的内部访问了接收器e Employee

package main

import (
    "fmt"
)

type Employee struct {
    name     string
    salary   int
    currency string
}

func (e Employee) displaySalary() {
    fmt.Printf("Salary of %s is %s%d", e.name, e.currency, e.salary)
}

func main() {
    employ1 := Employee{
        name:     "wang",
        salary:   5000,
        currency: "$",
    }
    employ1.displaySalary()
}

输出:

Salary of wang is $5000

为什么已经有函数了还需要方法:

将上面的例子改写成函数:

package main

import (
    "fmt"
)

type Employee struct {
    name     string
    salary   int
    currency string
}

func displaySalary(e Employee) {
    fmt.Printf("Salary of %s is %s%d", e.name, e.currency, e.salary)
}

func main() {
    employ1 := Employee{
        name:     "wang",
        salary:   5000,
        currency: "$",
    }
    displaySalary(employ1)
}

输出:

Salary of wang is $5000

在上面的程序中,displaySalart 方法被转化为一个函数,Employee 结构体被当做参数传递给它,这个程序也产生完全相同的输出

为什么需要方法,有几个原因:

1、Go 不是纯粹的面向对象的编程语言,而且Go不支持类,因此,基于类型的方法是一种实现和类相似行为的途径。

2、相同的名字的方法可以定义在不同类型上,而相同名字的函数是不允许的。

指针接收器和值接收器

GO 方法里面还可以创建指针接收器的方法,值接收器和指针接收器的区别在于,在指针接收器的方法内部的改变对于调用者是可见的,然而值接收器的情况不是这样的

理解:值接收器传递的只是一个值,而指针接收器传递的是一个地址,指向该值的地址

如何选择指针接收器还是值接收器:

1、修改接收器状态:如果方法需要修改接收器的状态,Name通常应该使用指针接收器,这是因为指针接收器可以直接修改接收器指向的对象,而值接收器只是接收对象的副本,对其修改不会影响原始对象。

2、避免值拷贝:如果接收器的类型是较大的结构体或包含了大量数据的类型,而方法不需要修改接收器状态,但需要读取接收器的属性,那么应该考虑使用指针接收器,这可以避免在方法调用时发生不必要的值拷贝,提高程序的性能

3、一致性:如果在类型的方法中有一些方法需要修改接收器状态,而其他方法只是需要读取接收器的属性,那么应该保持一致性,统一使用指针接收器。

4、可空类型:如果类型的零值是合法的,并且在类型的实例在某些情况下可能为nil,那么应该使用指针接收器,这样可以更好处理nil接收器的情况,避免因为nil接收器调用方法而引发panic

示例:

package main

import (
    "fmt"
)

type Employee struct {
    name string
    age  int
}

// 使用值接收器的方法
func (e Employee) changeName(newName string) {
    e.name = newName
}

// 使用指针接收器的方法
func (e *Employee) changeAge(newAge int) {
    e.age = newAge
}

func main() {
    e := Employee{
        name: "wang",
        age:  20,
    }
    fmt.Printf("Employee name before change: %s", e.name)
    e.changeName("zhang")
    fmt.Printf("\nEmployee name after change: %s", e.name)
    fmt.Printf("\n\nEmployee age before change: %d", e.age)
    (&e).changeAge(21)
    fmt.Printf("\nEmployee age after change: %d", e.age)
}

输出:

Employee name before change: wang 
Employee name after change: wang 
Employee age before change: 20 
Employee age after change: 21

在上面的程序中,changeName方法有一个值接收器(e Employee),而changeAge 方法有一个指针接收器(e *Employee). 在changeName 方法中对Employee结构体的字段name所做的改变对调用者是不可见的,因此在程序调用e.chanName("zhang")这个方法前后打印出相同的名字,由于changeAge方法值使用指针(e *Employee)接收器的,所以在调用(&e).changeAge方法对age字段做出的改变对调用者将是可见的。

在上面的程序里使用了 (&e).changeAge(21)来调用changeAge方法,由于changeAge方法有一个指针接收器,所以使用(&e)来调用这个方法,其实没有这个必要,Go语言让我们可以直接使用e.changeAge(21),会被自动解释为 (&e).changeAge(21)

在方法中使用指针接收器和在函数中使用指针参数

和值参数类似,函数使用指针参数只接受指针,而使用指针接收器的方法可以使用值接收器和指针接收器

示例:

package main

import (
    "fmt"
)

type rectangle struct {
    length int
    width  int
}

func perimeter(r *rectangle) {
    fmt.Println("perimeter function output:", 2*(r.length+r.width))
}

func (r *rectangle) perimeter() {
    fmt.Println("perimeter method output:", 2*(r.length+r.width))
}

func main() {
    r := rectangle{
        length: 10,
        width:  5,
    }
    p := &r
    perimeter(p)
    p.perimeter()
    r.perimeter()
}

输出:

perimeter function output: 30 
perimeter method output: 30 
perimeter method output: 30

我们通过值接收器 r 来调用有指针接收器的方法 perimeter。这是被允许的,为了方便Go语言把代码 r.perimeter() 解释为 (&r).perimeter()。

在非结构体上的方法

package main

import (
    "fmt"
)

type myInt int

func (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)
}

上面的程序中,为int类型创建了一个类型别名myInt,定义了一个以myInt为接收器的方法add

输出:

Sum is 15

参考:

Go 系列教程 —— 17. 方法 - Go语言中文网 - Golang中文社区

相关推荐

  1. <span style='color:red;'>Go</span> <span style='color:red;'>方法</span>

    Go 方法

    2024-03-20 10:42:04      28 阅读
  2. Go 方法

    2024-03-20 10:42:04       17 阅读
  3. client-go使用方法

    2024-03-20 10:42:04       41 阅读
  4. go圣经 ——方法

    2024-03-20 10:42:04       14 阅读
  5. go方法定义

    2024-03-20 10:42:04       14 阅读
  6. Go中定义方法

    2024-03-20 10:42:04       42 阅读
  7. 一文了解 Go 方法

    2024-03-20 10:42:04       42 阅读
  8. go拼接字符串的方法

    2024-03-20 10:42:04       11 阅读
  9. Go语言入门:Go语言的方法,函数,接口】

    2024-03-20 10:42:04       35 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-20 10:42:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-20 10:42:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-20 10:42:04       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-20 10:42:04       20 阅读

热门阅读

  1. 前端小白的学习之路(less&scss)

    2024-03-20 10:42:04       23 阅读
  2. 科学计算教程 SciCompforChemists

    2024-03-20 10:42:04       18 阅读
  3. css如何通过媒体查询功能实现自动切换dark 模式

    2024-03-20 10:42:04       20 阅读
  4. Day13 栈与队列part02

    2024-03-20 10:42:04       19 阅读