go - 在结构定义之外使用方法的原因是什么?

标签 go methods struct

为什么我们要在结构的类型定义之外声明方法?例如:

type antenna struct {
    name string
    length float32
    girth float32
    bloodtype string
}

func (p *antenna) extend() {
    p.length += 10
}

在我看来,该方法可能是结构的一部分? (让我们暂时忽略结构应该是值类型)

type antenna struct {
    name string
    length float32
    girth float32
    bloodtype string

    func extend() {
        length += 10
    }
}

这更类似于传统的 OOP。除了“结构是值类型而类是引用类型”之外,我没有找到任何很好的解释为什么它是这样完成的。我知道其中的区别,但这对我来说不是一个令人满意的答案。无论如何都必须像这样调用该方法:

var x = antenna()
x.extend() 

那么将结构和方法分开有什么意义呢?让它们在代码中直观地组合在一起——就像在典型的 OOP 语言中一样——对我来说似乎很有用?

最佳答案

TLR:代码重用一致性

1 - 这使得能够重用方法:
这是 Go 中 interface 类型的关键设计原则——让我用一个例子更清楚地说明:假设你需要对 int 的 slice 进行排序(试试 here ):

    a := []int{1, 3, 2, 5, 4}
    sort.Ints(a)   // sort.Sort(sort.IntSlice(a))
    fmt.Println(a) // [1 2 3 4 5]

您只需调用 sort.Ints(a),然后调用标准库中的 Sort(IntSlice(a)):

type IntSlice []int

func (x IntSlice) Len() int           { return len(x) }
func (x IntSlice) Less(i, j int) bool { return x[i] < x[j] }
func (x IntSlice) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }

sort.IntSlice 附加sort.Interface的3个方法:Len, Less,并将交换[]int类型,调用:

// Sort sorts data in ascending order as determined by the Less method.
// It makes one call to data.Len to determine n and O(n*log(n)) calls to
// data.Less and data.Swap. The sort is not guaranteed to be stable.
func Sort(data Interface) {
    n := data.Len()
    quickSort(data, 0, n, maxDepth(n))
}

因此您可以重用标准库中的方法,并且不需要重新实现


2- 您可以定义自己的类型,请参见 this 示例 - 此命名类型 没有inside - 因此方法必须在outside strong> 这种类型的:

package main

import "fmt"

type num int32

func (p *num) inc() {
    *p++
}

func main() {
    p := num(100)
    p.inc()
    fmt.Println(p) // 101
}

上面的命名类型 num 与这个用户定义的类型:通过设计,这使得 Go 语言一致对于这两种类型:


type Animal struct {
    Name  string
    moves []move.Direction
}

func (p *Animal) Walk(dir move.Direction) {
    p.moves = append(p.moves, dir)
}

另见:
In Go is naming the receiver variable 'self' misleading or good practice?

关于go - 在结构定义之外使用方法的原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53387303/

相关文章:

go - 使用 'go build' 获取依赖项,即使它们位于 vendor/中

mysql - 在 Go 中访问 MySQL 查询结果的第二行

java - 如何在 HashMap 中添加、删除和保存值

C++,改变属于一个类的结构对象的值

c - typedef struct 让指针成为下一个指向节点是什么意思?

go - 如何在 Go 编程语言中可靠地 unlink() Unix 域套接字

go - 按键分组+合并数组值

java - 较小的方法

java - 方法引用 Static - 小程序示例给建议

C 指针、链表和节点