2016-02-03 38 views
1

我知道func和method之間的區別。但我困惑的之間的用法:方法與函數的用法golang

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

或:

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

我不知道這是爲什麼下投了那麼多,但我認爲這是一個完全有效的問題。 – Danilo

回答

3

這是兩種截然不同的情況,其中之一是方法屬於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") 

通常在您的場景中,第一種方法是首選,因爲它封裝了管理其屬性的功能。

第二種情況可能被看作是「類方法方法」(對於來自像Python或Java這樣的OOP的方法),其中包類似於類,並且暴露的函數類似於更通用的類方法,可以是

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") 
} 
+0

非常感謝您的詳細解釋! – LanMan

2

這是預期按規範:

該類型的方法是一種功能與類型接收者作爲第一個參數。

https://golang.org/ref/spec#Method_declarations

所以,當你聲明Add方法上Product,你接受一個指向Product作爲第一個參數的函數。所以,你最終

func (p *Product) Add() 

被翻譯成

func Add(p *Product) 

因此,無論您的來電是有效的,並最終做同樣的