我知道func和method之間的區別。但我困惑的之間的用法:方法與函數的用法golang
prod:=Product{"title","brand","model"}
prod.Add()
或:
prod:=Product{"title","brand","model"}
products.Add(&prod) // products is package
我知道func和method之間的區別。但我困惑的之間的用法:方法與函數的用法golang
prod:=Product{"title","brand","model"}
prod.Add()
或:
prod:=Product{"title","brand","model"}
products.Add(&prod) // products is package
這是兩種截然不同的情況,其中之一是方法屬於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")
}
非常感謝您的詳細解釋! – LanMan
這是預期按規範:
該類型的方法是一種功能與類型接收者作爲第一個參數。
見https://golang.org/ref/spec#Method_declarations
所以,當你聲明Add
方法上Product
,你接受一個指向Product
作爲第一個參數的函數。所以,你最終
func (p *Product) Add()
被翻譯成
func Add(p *Product)
因此,無論您的來電是有效的,並最終做同樣的
我不知道這是爲什麼下投了那麼多,但我認爲這是一個完全有效的問題。 – Danilo