英文:
Syntax of a function
问题
我正在查看Golang文档中的“编写Web应用程序”章节,并找到了以下函数的语法:
func (p *Page) save() error {
filename := p.Title + ".txt"
return os.WriteFile(filename, p.Body, 0600)
}
从文档中可以看到,这是一个名为save
的方法,它以指向Page
的指针p
作为接收器。它不接受任何参数,并返回一个error
类型的值。
- 声明函数时,使用
func save(p *Page) error{}
的方式有什么区别?接收器和函数参数之间有什么区别?- 使用接收器的方式可以将函数与特定类型关联起来,使其成为该类型的方法。这样,我们可以通过该类型的实例来调用该方法。而使用函数参数的方式则将函数作为独立的实体,需要通过传递参数来调用。
- 为什么返回一个
error
类型的值,而我看到它返回的是os
包中的一个函数?- 在这个例子中,
os.WriteFile
函数返回一个error
类型的值,表示文件写入操作可能会出现错误。通过返回该值,我们可以在调用该方法的地方进行错误处理。
- 在这个例子中,
希望对你有帮助!如果还有其他问题,请随时提问。
英文:
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,
答案1
得分: 1
func save(p *Page) error{}
和func (p *Page) save() error
之间的区别是什么?接收器和函数参数之间的区别是什么?
这两种方式在功能上是相同的,这是Go在编译时的底层操作。但是它们有一些语义上的区别:
- 最大的区别是,你可以像这样调用
func (p *Page) save() error
:somePage.save()
,而调用func save(p *Page) error
则是save(somePage)
。 - 通过go.dev生成的文档将把它列为包中的一个函数,而不是
Page
的方法(假设它是一个导出的函数)。 - 声明一个
func save(p *Page) error
不会使Page
实现一个接口,比如interface{ save() }
,而方法会实现该接口。 - 当调用方法时,Go会自动在指针和值之间进行转换,但是对于函数,你必须始终自己传递正确的参数类型。例如:
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"}
// 两种方式都可以工作
fmt.Println(p.String())
fmt.Println(p.PtrString()) // 这里隐式地传递了一个指针
// 这种方式可以工作
fmt.Println(PageString(p))
// 这个无法编译通过
fmt.Println(PagePtrString(p)) // cannot use p (type Page) as type *Page in argument to PagePtrString
// 但是这个可以,你必须指定你要传递一个指针
fmt.Println(PagePtrString(&p))
}
这里有一个链接,详细介绍了指针接收器和值接收器之间的区别。
- 当我看到它返回一个
error
类型的值时,为什么它返回的是os
包中的一个函数?
它并不返回函数本身,它调用了os.WriteFile
的返回值,而该返回值是error
类型的。
英文:
> 1. 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.
> 2. 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论