Go中函数和方法有什么区别?

问题描述 投票:0回答:6

我正在尝试开始使用 Go,并且 文档 非常好。我在文档中没有找到函数和方法之间的区别。

据我目前的理解:函数是“全局”的,这意味着我不必导入包来使用函数,它们总是存在的。方法绑定到包。这是正确的吗?

function methods go
6个回答
138
投票

据我目前的理解:函数是“全局”的,这意味着我不必导入包来使用函数,它们总是存在的。方法绑定到包。这是正确的吗?

不,那是不正确的。 builtin 包中只有几个函数始终可用。其他一切都需要进口。

“方法”一词是在面向对象编程中提出的。在 OOP 语言(例如 C++)中,您可以定义一个“类”来封装属于一起的数据和函数。类中的这些函数称为“方法”,您需要该类的实例才能调用此类方法。

在 Go 中,术语基本相同,尽管 Go 不是经典意义上的 OOP 语言。在 Go 中,带有接收者的函数通常被称为方法(可能只是因为人们仍然习惯 OOP 的术语)。

所以,例如:

func MyFunction(a, b int) int {
  return a + b
}
// Usage:
// MyFunction(1, 2)

但是

type MyInteger int
func (a MyInteger) MyMethod(b int) int {
  return a + b
}
// Usage:
// var x MyInteger = 1
// x.MyMethod(2)

31
投票

Tux 的答案很好,但我想通过使用 Go 的方法和

struct
s 来增强它(因为这是我经常使用它的地方)。因此,我们假设您想要构建一些东西来计算三角形的各种方法。你从
struct
开始:

type Triangle struct {
    a, b, c float64
}

然后你想添加一些函数来计算周长和平方:

func valid(t *Triangle) error {
    if t.a + t.b > t.c && t.a + t.c > t.b && t.b + t.c > t.a {
        return nil
    }
    return errors.New("Triangle is not valid")
}

func perimeter(t *Triangle) (float64, error) {
    err := valid(t)
    if err != nil {
        return -1, err
    }

    return t.a + t.b + t.c, nil
}

func square(t *Triangle) (float64, error) {
    p, err := perimeter(t)
    if err != nil {
        return -1, err
    }

    p /= 2
    s := p * (p - t.a) * (p - t.b) * (p - t.c)
    return math.Sqrt(s), nil
}

现在您已获得工作程序Go Playground。在这种情况下,您的函数接受一个参数(指向三角形的指针)并执行某些操作。在 OOP 中,人们可能创建了一个类,然后添加了方法。我们可以将我们的结构视为带有字段的类,现在我们添加方法:

func (t *Triangle) valid() error {
    if t.a + t.b > t.c && t.a + t.c > t.b && t.b + t.c > t.a {
        return nil
    }
    return errors.New("Triangle is not valid")
}

func (t *Triangle) perimeter() (float64, error) {
    err := t.valid()
    if err != nil {
        return -1, err
    }

    return t.a + t.b + t.c, nil
}

func (t *Triangle) square() (float64, error) {
    p, err := t.perimeter()
    if err != nil {
        return -1, err
    }

    p /= 2
    s := p * (p - t.a) * (p - t.b) * (p - t.c)
    return math.Sqrt(s), nil
}

我们有一个完整的工作示例

请注意,它看起来真的很像对象的方法。


23
投票

它们在这里详细解释 - https://anil.cloud/2017/01/26/golang-functions-methods-simplified/

Go 中的函数遵循以下语法:

func FunctionName(Parameters...) ReturnTypes...

示例:

func add(x int, y int) int

执行:

  add(2,3) 

方法就像一个函数,但附加到一个类型(称为接收者)。官方指南指出“方法是具有特殊接收器参数的函数”。接收者出现在 func 关键字和方法名称之间。方法的语法是:

func (t ReceiverType) FunctionName(Parameters...) ReturnTypes...

示例:

func (t MyType) add(int x, int y) int

执行:

type MyType string
t1 := MyType("sample")
t1.add(1,2)

现在让我们将指针带入表中。 Go lang 是按值传递的,意味着参数的新副本将传递给每个函数/方法调用。要通过引用传递它们,您可以使用指针。

参数/参数列表中带有指针的函数语法。

func FunctionName(*Pointers...,Parameters...) ReturnTypes...

示例

func add(t *MyType, x int, y int) int

执行:

type MyType string
t1 := MyType("sample")
add(&t1,4,5)

与方法类似,接收者类型可以是指针。带指针的方法的语法(作为接收者)

func (*Pointer) FunctionName(Parameters...) ReturnTypes...

示例

func (t *MyType) add(x int, y int) int

执行:

type MyType string
t1 := MyType("sample")
t1.add(2,3)

请注意,我们仍然可以编写 t1.add() 来使用指针接收器执行该方法(即使“t1”不是指针),Go 会将其解释为 (&t1).add()。类似地,也可以使用指针调用带有值接收器的方法,在这种情况下,Go 会将 p.add() 解释为 (*p).add() (其中“p”是指针)。这仅适用于方法,不适用于函数。

带有指针接收器的方法对于获得类似“Java”的行为非常有用,其中该方法实际上是修改接收器指向的值而不是其副本。


0
投票

Go 方法与 Go 函数类似,但有一个区别,即该方法中包含一个接收者参数。在接收者参数的帮助下,该方法可以访问接收者的属性。这里,接收者可以是结构体类型,也可以是非结构体类型。

func(reciver_name Type) method_name(parameter_list)(return_type){
    // Code
}

0
投票

以上答案对我来说似乎不错。除此之外我还想补充一下。

Function
是从包 调用的东西。而
method
也是一个 函数,但从特定类型值 调用。
values
是函数的返回。

例如:

  1. rightNow := time.Now()

time
--> 包,
Now()
--> 函数,因为由包调用,
rightNow
value
time 的
type
。从 Now() 函数返回的时间。

  1. year := rightNow.Year()

rightNow
--> value,
Year()
-->
function
但由于它是由某个
value
(这里是 time.Time)的
type
调用的,因此它被称为
Method
。为了方便识别,方法有一个与调用它的类型相同的接收器。


0
投票
The words function and method are used almost interchangeably, but there are subtle differences in their implementation and usage when used in Golang .
Hailing from Java or any other object-oriented language background, the first instinct is to use structs and methods for everything since objects always have a behaviour defined by their methods .

But is that a right approach in Golang where we have functions and methods both ?
Let’s first understand what is a function and what is a method in Golang .

A function takes a few parameters as input and produces some output.
For the same input, the function will always produce the same output.
That means it’s not dependent on the state. Type is always passed as an argument to the function .
© www.soinside.com 2019 - 2024. All rights reserved.