方法与函数用法golang

I know differences between func and method. But I am confusing for usages between:

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

or:

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

These are two distinct cases, one which is a method belongs to Product instance and one is a global function belongs to products package.

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
        }
}

The above provide a method to add value to itself as an instance of Product, i.e.

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

The second case is a public function exposed from a product package. In this case, an instance (or a pointer) of a Product must be supplied as an argument.

package products

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

Add function then can be used from any other package.

package main

import (
        "path/to/products"
)

type Product struct {
        // ...
}

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

Normally in your scenario, the first approach is preferred since it encapsulates the functionality of managing its attributes to itself.

The second scenario might be seen as a "class method approach" (for those coming from OOP like Python or Java) where the package is similar to class and the exposed functions similar to class methods which are more generic and can be used across many types which implement the same interface, like so:

package products

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

type Product interface {
        someMethod()
}

And from another package:

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

This is expected as per the spec:

The type of a method is the type of a function with the receiver as first argument.

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

So when you declare the Add method on Product, you get a function that accepts a pointer to a Product as its first argument. So you end up with

func (p *Product) Add() 

being translated to

func Add(p *Product)

So both your calls are valid and end up doing the same