- What is the difference between declaring the function like this
func save(p *Page) error{}
? What is the difference between a receiver and a function parameter?
These are functionally identical, this is what Go does underwater when compiling. But there are a few semantic differences:
- The largest difference is that you would call
func (p *Page) save() error
like somePage.save()
and func save(p *Page) error
as save(somePage)
.
- Documentation generated by go.dev will list it as a function in the package, not as method for
Page
(assuming it was an exported function).
- When declaring a func like
func save(p *Page) error
will not make Page
implement an interface like interface{ save() }
where as the method will.
- Go will convert between pointers and values for you when calling a method, but for functions you must always pass the correct param type yourself. For example:
type Page struct {
Field string
}
func (p *Page) PtrString() string {
return p.Field
}
func (p Page) String() string {
return p.Field
}
func PageString(page Page) string {
return page.Field
}
func PagePtrString(page *Page) string {
return page.Field
}
func main() {
p := Page{Field: "Hello world"}
// Both work
fmt.Println(p.String())
fmt.Println(p.PtrString()) // This passes a pointer implicitly
// This works
fmt.Println(PageString(p))
// This doesn't compile
fmt.Println(PagePtrString(p)) // cannot use p (type Page) as type *Page in argument to PagePtrString
// But this does, you have to specify you want to pass a pointer
fmt.Println(PagePtrString(&p))
}
Here is a link with more details about the difference between pointer and value receivers.
- Why is it returning a value of type error, when I see it is returning a function from the os package?
It doesn't return the function itself, it calls it and returns the return value of os.WriteFile
, which is error