Go 方法

2 篇文章 0 订阅

什么是方法:

方法其实就是一个函数,在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中文社区

  • 13
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Gradio是一个用于快速构建机器学习界面的Python库,它主要依赖于Flask和Werkzeug等库来搭建Web应用程序。如果您需要在Gradio中调用Go语言方法,您需要先将Go方法编译成可执行文件,然后通过Gradio的接口来调用该可执行文件。 具体来说,您需要编写一个Python函数来启动Go可执行文件,并将其作为子进程运行。在这个Python函数中,您可以使用Python的subprocess模块来启动Go可执行文件,并使用标准输入和输出流与该进程进行通信。然后,您可以将Gradio的输入传递给子进程,并将子进程的输出作为Gradio的输出返回。 下面是一个简单的示例代码,演示如何在Gradio中调用Go可执行文件: ```python import subprocess def go_method(input): # 启动Go可执行文件 process = subprocess.Popen(['./path/to/go/executable'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) # 将输入传递给子进程 process.stdin.write(input.encode()) process.stdin.flush() # 读取子进程的输出 output = process.stdout.readline().decode() # 关闭子进程 process.stdin.close() process.stdout.close() process.wait() # 返回输出 return output ``` 在这个示例中,我们假设Go可执行文件是在当前目录中的,您需要将`./path/to/go/executable`替换为实际的Go可执行文件路径。此外,这个示例只处理单行输入和输出,如果您的Go方法需要处理更复杂的输入和输出,请根据实际情况进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值