Nat*_*n H 5 error-handling pointers pass-by-reference go
阅读有关Web和stackoverflow上的值接收器与指针接收器的信息,我了解以下基本规则:如果您不打算修改接收器,并且接收器相对较小,则不需要指针。
然后,阅读有关实现error
接口的信息(例如https://blog.golang.org/error-handling-and-go),我看到该Error()
函数的示例全部使用指针接收器。
但是,我们没有修改接收器,结构非常小。
我觉得没有指针(return &appError{}
vs return appError{}
)的代码会更好。
示例使用指针有原因吗?
icz*_*cza 10
首先,你联系,把您的示例中的博客文章,appError
是不是一个error
。它是一个包装器,用于承载错误值和示例实现所使用的其他相关信息,它们不会公开,appError
也*appError
永远不会用作error
值。
因此,您引用的示例与您的实际问题无关。但是要回答标题中的问题:
通常,一致性可能是原因。如果一个类型有很多方法并且有些需要指针接收器(例如,因为它们修改了值),那么通常使用指针接收器声明所有方法会很有用,因此不会混淆类型和指针类型的方法集。
关于error
实现的回答:当您使用struct
值实现error
值时,使用非指针实现error
接口是很危险的。为什么会这样呢?
因为error
是一个接口。并且接口值是可比的。通过比较它们包装的值来比较它们。您会根据其中包含的值/类型获得不同的比较结果!因为如果在其中存储指针,则如果它们存储相同的指针,则错误值将相等。并且,如果将非指针(结构)存储在它们中,则当结构值相等时它们也将相等。
要对此进行详细说明并显示一个示例:
标准库有一个errors
软件包。您可以string
使用errors.New()
函数根据值创建错误值。如果看一下它的实现(errors/errors.go
),它很简单:
// Package errors implements functions to manipulate errors.
package errors
// New returns an error that formats as the given text.
func New(text string) error {
return &errorString{text}
}
// errorString is a trivial implementation of error.
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
Run Code Online (Sandbox Code Playgroud)
该实现返回一个指向非常简单的struct值的指针。这样,如果您创建两个具有相同string
值的错误值,它们将不相等:
e1 := errors.New("hey")
e2 := errors.New("hey")
fmt.Println(e1, e2, e1 == e2)
Run Code Online (Sandbox Code Playgroud)
输出:
hey hey false
Run Code Online (Sandbox Code Playgroud)
这是故意的。
现在,如果您要返回非指针:
func New(text string) error {
return errorString{text}
}
type errorString struct {
s string
}
func (e errorString) Error() string {
return e.s
}
Run Code Online (Sandbox Code Playgroud)
2个相同的错误值string
将相等:
e1 = New("hey")
e2 = New("hey")
fmt.Println(e1, e2, e1 == e2)
Run Code Online (Sandbox Code Playgroud)
输出:
hey hey true
Run Code Online (Sandbox Code Playgroud)
在Go Playground上尝试示例。
一个为什么如此重要的闪亮示例:查看存储在变量中的错误值io.EOF
:
var EOF = errors.New("EOF")
Run Code Online (Sandbox Code Playgroud)
期望io.Reader
实现将这个特定的错误值返回给信号输入结束。因此,您可以和平比较返回的错误Reader.Read()
,io.EOF
以判断是否到达输入结束。您可以确定,如果它们偶尔返回自定义错误,则它们将永远不会等于io.EOF
,这是可以errors.New()
保证的(因为它返回了指向未导出结构值的指针)。
不 :)
https://blog.golang.org/error-handling-and-go#TOC_2。
Go 接口允许任何符合错误接口的内容由期望的代码处理error
type error interface {
Error() string
}
Run Code Online (Sandbox Code Playgroud)
就像您提到的,如果您不打算修改状态,则几乎没有动力传递指针:
有趣的是,我个人认为看到这样的例子就是新的 Go 程序员默认青睐指针接收器的原因。
归档时间: |
|
查看次数: |
2264 次 |
最近记录: |