如何在 Go 中创建多级错误子类型
How to create multi-level Error subtypes in Go
我试图在 GO 中创建错误的子类型。 关于此事。
现在我遇到了多种类型的问题。以下代码显示错误类型定义:
/* Interfaces */
type UniversalError interface {
CommonError1
}
type CommonError1 interface {
error
CommonError1()
}
/* Structs */
type Error1 struct {
reason string
}
type Error2 struct {
reason string
}
type Error3 struct {
reason string
}
/* Interface function implementations */
func (error1 Error1) Error() string {
return fmt.Sprintf(error1.reason)
}
func (error2 Error2) Error() string {
return fmt.Sprintf(error2.reason)
}
func (error3 Error3) Error() string {
return fmt.Sprintf(error3.reason)
}
func (Error1) CommonError1() {}
func (Error2) CommonError1() {}
func (Error3) UniversalError() {}
当我尝试运行以下代码时:
func main() {
var err1 = Error1{reason: "Error reason 1"}
var err2 = Error2{reason: "Error reason 2"}
var err3 = Error3{reason: "Error reason 3"}
fmt.Println("\n**** Types *****")
printType(err1)
printType(err2)
printType(err3)
}
func printType(param error) {
switch param.(type) {
case UniversalError:
switch param.(type) {
case CommonError1:
switch param.(type) {
case Error1:
fmt.Println("Error1 found")
case Error2:
fmt.Println("Error2 found")
default:
fmt.Println("CommonError1 found, but Does not belong to Error1 or Error2")
}
default:
fmt.Println("Error3 Found")
}
default:
fmt.Println("Error belongs to an unidentified type")
}
}
printType()
函数打印以下内容:
**** Types *****
Error1 found
Error2 found
CommonError1 found, but Does not belong to Error1 or Error2
我需要 Error3
的类型被识别为 UniversalError
,而不是 CommonError1
。我怎样才能做到这一点?我的方法有什么问题吗?
您使用了 UniversalError()
方法,但您没有将其添加到界面 "definition",所以这样做:
type UniversalError interface {
CommonError1
UniversalError()
}
并且您希望 Error3
成为 UniversalError
。要使 Error3
成为 UniversalError
,它必须实现其所有方法:UniversalError()
和 CommonError1()
。所以你必须添加这两种方法:
func (Error3) CommonError1() {}
func (Error3) UniversalError() {}
进行这些更改后,输出将是(在 Go Playground 上尝试):
**** Types *****
Error belongs to an unidentified type
Error belongs to an unidentified type
CommonError1 found, but Does not belong to Error1 or Error2
提示:如果你想compile-time保证一些具体类型实现了一些接口,使用像这样的空白变量声明:
var _ UniversalError = Error3{}
上面的声明将Error3
的值赋给UniversalError
类型的变量。如果 Error3
不满足 UniversalError
,您将收到 compile-time 错误。上面的声明不会引入新变量,因为使用了 blank identifier,这只是一个 compile-time 检查。
如果您要删除 Error3.CommonError1()
方法:
//func (Error3) CommonError1() {}
func (Error3) UniversalError() {}
然后你会立即得到一个 compile-time 错误:
./prog.go:49:5: cannot use Error3 literal (type Error3) as type UniversalError in assignment:
Error3 does not implement UniversalError (missing CommonError1 method)
我试图在 GO 中创建错误的子类型。
现在我遇到了多种类型的问题。以下代码显示错误类型定义:
/* Interfaces */
type UniversalError interface {
CommonError1
}
type CommonError1 interface {
error
CommonError1()
}
/* Structs */
type Error1 struct {
reason string
}
type Error2 struct {
reason string
}
type Error3 struct {
reason string
}
/* Interface function implementations */
func (error1 Error1) Error() string {
return fmt.Sprintf(error1.reason)
}
func (error2 Error2) Error() string {
return fmt.Sprintf(error2.reason)
}
func (error3 Error3) Error() string {
return fmt.Sprintf(error3.reason)
}
func (Error1) CommonError1() {}
func (Error2) CommonError1() {}
func (Error3) UniversalError() {}
当我尝试运行以下代码时:
func main() {
var err1 = Error1{reason: "Error reason 1"}
var err2 = Error2{reason: "Error reason 2"}
var err3 = Error3{reason: "Error reason 3"}
fmt.Println("\n**** Types *****")
printType(err1)
printType(err2)
printType(err3)
}
func printType(param error) {
switch param.(type) {
case UniversalError:
switch param.(type) {
case CommonError1:
switch param.(type) {
case Error1:
fmt.Println("Error1 found")
case Error2:
fmt.Println("Error2 found")
default:
fmt.Println("CommonError1 found, but Does not belong to Error1 or Error2")
}
default:
fmt.Println("Error3 Found")
}
default:
fmt.Println("Error belongs to an unidentified type")
}
}
printType()
函数打印以下内容:
**** Types *****
Error1 found
Error2 found
CommonError1 found, but Does not belong to Error1 or Error2
我需要 Error3
的类型被识别为 UniversalError
,而不是 CommonError1
。我怎样才能做到这一点?我的方法有什么问题吗?
您使用了 UniversalError()
方法,但您没有将其添加到界面 "definition",所以这样做:
type UniversalError interface {
CommonError1
UniversalError()
}
并且您希望 Error3
成为 UniversalError
。要使 Error3
成为 UniversalError
,它必须实现其所有方法:UniversalError()
和 CommonError1()
。所以你必须添加这两种方法:
func (Error3) CommonError1() {}
func (Error3) UniversalError() {}
进行这些更改后,输出将是(在 Go Playground 上尝试):
**** Types *****
Error belongs to an unidentified type
Error belongs to an unidentified type
CommonError1 found, but Does not belong to Error1 or Error2
提示:如果你想compile-time保证一些具体类型实现了一些接口,使用像这样的空白变量声明:
var _ UniversalError = Error3{}
上面的声明将Error3
的值赋给UniversalError
类型的变量。如果 Error3
不满足 UniversalError
,您将收到 compile-time 错误。上面的声明不会引入新变量,因为使用了 blank identifier,这只是一个 compile-time 检查。
如果您要删除 Error3.CommonError1()
方法:
//func (Error3) CommonError1() {}
func (Error3) UniversalError() {}
然后你会立即得到一个 compile-time 错误:
./prog.go:49:5: cannot use Error3 literal (type Error3) as type UniversalError in assignment:
Error3 does not implement UniversalError (missing CommonError1 method)