方法与函数用法golang

时间:2016-02-03 20:51:45

标签: go

我知道func和方法之间的区别。但我对以下用法感到困惑:

prod:=Product{"title","brand","model"}
prod.Add()

或:

prod:=Product{"title","brand","model"}
products.Add(&prod) // products is package

3 个答案:

答案 0 :(得分:4)

这是两个截然不同的案例,一个是方法属于Product个实例,一个是全局函数属于products个包

type Product struct {
        Title string
        Brand string
        Model string
}

// This method add value to a field in Product
func (p *Product) Add(field, value string) {
        switch field {
        case "Title":
                p.Title = value
        case "Brand":
                p.Brand = value
        case "Model":
                p.Model = value
        }
}

以上提供了一种向自身添加值的方法,作为Product的实例,即

product1 := &Product{}
product1.Add("Title", "first_title")

第二种情况是从product包公开的公共功能。在这种情况下,必须提供Product的实例(或指针)作为参数。

package products

func Add(p *Product, field, value string) {
        // Same switch-case as above
}

Add函数可以在任何其他包中使用。

package main

import (
        "path/to/products"
)

type Product struct {
        // ...
}

func main() {
        product1 := &Product{}
        products.Add(product1, "Title", "first_title")

通常在您的场景中,第一种方法是首选方法,因为它封装了管理其属性的功能。

第二种情况可能被视为“类方法方法”(对于来自OOP的那些方法,如Python或Java),其中包类似于类,并且公开的函数类似于更通用的类方法并且可以使用跨越许多实现相同接口的类型,如:

package products

// where p is a Product interface
func Add(p Product, field, value string) {
        // Same switch-case as above
}

type Product interface {
        someMethod()
}

从另一个包中:

package main

import (
        "path/to/products"
)

type Car struct {
        Title string
        Brand string
        Model string
}

type Ship struct {
        // ...
}

type Airplane struct {
        // ...
}

// All types implement `Product` and can be used in `products.Add`
func (c *Car) someMethod() {}
func (s *Ship) someMethod() {}
func (a *Airplane) someMethod() {}

func main() {
       plane := &Airplane{}
       products.Add(plane, "Model", "Boeing-747")
}

答案 1 :(得分:2)

根据规范预期:

  

方法的类型是以接收者作为第一个参数的函数的类型。

请参阅https://golang.org/ref/spec#Method_declarations

因此,当您在Add上声明Product方法时,您将获得一个函数,该函数接受指向Product的指针作为其第一个参数。所以你最终得到了

func (p *Product) Add() 

被翻译为

func Add(p *Product)

所以你的两个电话都是有效的,并最终做同样的

答案 2 :(得分:0)

扩展@Danilo的精彩回答:

package main

import "fmt"

type T struct {
    i int
}

func (t *T) F() {
    t = &T{1}
    fmt.Println(t.i)
}

func F(t *T) {
    fmt.Println(t.i)
}

func main() {
    t := T{2}
    (&t).F()
    F(&t)
}

方法func (t *T) F()的类型是函数func F(t *T)的类型,其中接收者(t *T)作为第一个参数。