英文:
Impossible type switch case
问题
这个程序无法编译:
package main
type Validator struct {
}
// Error 实现了 error 接口
func (v *Validator) Error() string {
return ""
}
func test() error {
return &Validator{}
}
func main() {
switch test().(type) {
case nil:
println("没有错误")
case Validator:
println("验证错误")
return
default:
println("未知错误")
return
}
}
错误信息为:
prog.go:19: 不可能的类型切换情况:test()(类型为 error)不能具有动态类型 Validator(缺少 Error 方法)
但是 Validator
结构体有 Error
方法。
英文:
This program does not compile:
package main
type Validator struct {
}
// Error implements error interface
func (v *Validator) Error() string {
return ""
}
func test() error {
return &Validator{}
}
func main() {
switch test().(type) {
case nil:
println("No error")
case Validator:
println("Validation error")
return
default:
println("Unknown error")
return
}
}
The error is:
prog.go:19: impossible type switch case: test() (type error) cannot have dynamic type Validator (missing Error method)
But Validator
struct has method Error
.
答案1
得分: 16
你有两种不同的类型,Validator
和指针类型*Validator
,这两种类型有不同的方法集。
你只为指针类型定义了一个Error()
方法,而Validator
没有这个方法。
你可以进行以下更改:
// Error实现了error接口
func (v Validator) Error() string {
return ""
}
...
case *Validator, Validator: // 实际上你得到的是一个*Validator
这样就为Validator
和*Validator
都实现了Error()
方法。正如**Go规范**所说:
任何其他类型T的方法集包含所有以接收器类型T声明的方法。
相应指针类型T的方法集是所有以接收器类型T或T声明的方法的集合(也就是说,它还包含T的方法集)。
英文:
You have two different types, Validator
and the pointer type *Validator
, and these two types have different method sets.
You have only defined an Error()
method for the pointer while Validator
doesn't have this method.
What you can do is the following change:
// Error implements error interface
func (v Validator) Error() string {
return ""
}
...
case *Validator, Validator: // You are actually getting a *Validator
This implements Error()
for both Validator
and *Validator
. As the Go specification says:
>The method set of any other type T consists of all methods declared with receiver type T.
>The method set of the corresponding pointer type *T is the set of all methods declared with
>receiver *T or T (that is, it also contains the method set of T)
答案2
得分: 8
编译器是正确的。Validator
类型没有实现 Error
接口,而 *Validator
实现了。Validator
和 *Validator
是不同的类型。只需在类型切换中将前者替换为后者:
switch test().(type) {
case nil:
println("没有错误")
case *Validator:
println("验证错误")
return
default:
println("未知错误")
return
}
在 Go Playground 上的工作示例:http://play.golang.org/p/aWqzPXweiA
英文:
The compiler is correct. Validator
type does not implement Error
, *Validator
does. Validator
and *Validator
are different types. Just replace the former with the latter in the type switch:
switch test().(type) {
case nil:
println("No error")
case *Validator:
println("Validation error")
return
default:
println("Unknown error")
return
}
Working example on the Go Playground: http://play.golang.org/p/aWqzPXweiA
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论