Syntax of a function
I am looking into the chapter Writing Web Application
of the Golang docs, and found this syntax of a function:
func (p *Page) save() error {
filename := p.Title + ".txt"
return os.WriteFile(filename, p.Body, 0600)
}
And from the docs... This is a method named save that takes as its receiver p, a pointer to Page . It takes no parameters, and returns a value of type error.
- 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? - Why is it returning a value of type error, when I see it is returning a function from the
os
package?
Thank you in advance, may be a dumb question but I'm kinda new to Golang,
- 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
likesomePage.save()
andfunc save(p *Page) error
assave(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 makePage
implement an interface likeinterface{ 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