英文:
Go: Returning always nil error to implement interface
问题
我有一个interface
:
type encoder interface {
encode() ([]byte, error)
}
一些encoder
的实现会返回一个error
:
type fooEncoder string
func (e fooEncoder) encode() ([]byte, error) {
if isSomeValidityCheck(e) {
return []byte(e), nil
}
return nil, fmt.Errorf("Invalid type!")
}
但对于其他实现,永远不会有错误:
type boolEncoder bool
func (e boolEncoder) encode() ([]byte, error) {
if e {
return []byte{0xff}, nil
}
return []byte{0x00}, nil
}
一个方法即使总是返回nil
,为了符合interface
,是否说它会返回一个错误是符合惯例/正确的?我让boolEncoder.encode
返回一个error
只是为了符合encoder
并且可以作为encoder
使用。
英文:
I have an interface
:
type encoder interface {
encode() ([]byte, error)
}
Some implementations of encoder
return an error
:
type fooEncoder string
func (e fooEncoder) encode() ([]byte, error) {
if isSomeValidityCheck(e) {
return []byte(e), nil
}
return nil, fmt.Errorf("Invalid type!")
}
But for others, there will never be an error:
type boolEncoder bool
func (e boolEncoder) encode() ([]byte, error) {
if e {
return []byte{0xff}, nil
}
return []byte{0x00}, nil
}
Is it idiomatic/correct to say a method will return an error, even if it will always be nil
, so that it conforms to an interface
? I have boolEncoder.encode
returning an error
only so that it conforms to encoder
and can be used as such.
答案1
得分: 1
这是完全可以的/正常的。通常,实现接口比减少方法的代码更重要。
标准库中也有很多例子。
例如,bytes/Buffer.Write()
使用以下方式实现了 io.Writer
:
func (b *Buffer) Write(p []byte) (n int, err error)
但是,向内存缓冲区写入不会失败,它记录了它永远不会返回非nil
错误:
> Write将p的内容附加到缓冲区,根据需要扩展缓冲区。返回值n是p的长度;err始终为nil。如果缓冲区变得太大,Write将使用ErrTooLarge引发panic。
Buffer.Write()
可以有一个不返回任何内容的签名,因为它的返回值不包含任何信息(n
始终是len(p)
,err
始终是nil
),但是这样你就无法将bytes.Buffer
用作io.Writer
,这更重要。
参考链接:https://stackoverflow.com/questions/40950877/is-unnamed-arguments-a-thing-in-go/40951013#40951013;和https://stackoverflow.com/questions/22549228/why-does-go-allow-compilation-of-unused-function-parameters/33759531#33759531
英文:
This is completely OK / normal. Often it's more important to implement an interface than to reduce the code (of the method).
There are numerous examples in the standard lib too.
For example bytes/Buffer.Write()
implements io.Writer
with
func (b *Buffer) Write(p []byte) (n int, err error)
But writing to an in-memory buffer cannot fail, it documents that it never will return a non-nil
error:
> Write appends the contents of p to the buffer, growing the buffer as needed. The return value n is the length of p; err is always nil. If the buffer becomes too large, Write will panic with ErrTooLarge.
Buffer.Write()
could have a signature that doesn't return anything because its return values carry no information (n
is always len(p)
and err
is always nil
), but then you couldn't use bytes.Buffer
as an io.Writer
, which is way more important.
See related: https://stackoverflow.com/questions/40950877/is-unnamed-arguments-a-thing-in-go/40951013#40951013; and https://stackoverflow.com/questions/22549228/why-does-go-allow-compilation-of-unused-function-parameters/33759531#33759531
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论