问题
I was trying to create sub-types of errors in GO. I've asked a question previously regarding the matter.
Now I'am facing an issue with the multiple types. Following code shows the error type definitions:
/* 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() {}
When I try to run the following code:
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")
}
}
The printType()
function prints the following:
**** Types *****
Error1 found
Error2 found
CommonError1 found, but Does not belong to Error1 or Error2
I need the type of Error3
to be identified as an UniversalError
, but not as a CommonError1
. How can I achieve this ? Is there anything wrong in my approach ?
回答1:
You use the UniversalError()
method, but you did not add that to the interface "definition", so do that:
type UniversalError interface {
CommonError1
UniversalError()
}
And you want Error3
to be a UniversalError
. For Error3
to be a UniversalError
, it must implement all its methods: UniversalError()
and CommonError1()
. So you have to add both those methods:
func (Error3) CommonError1() {}
func (Error3) UniversalError() {}
With these changes, output will be (try it on the 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
Tip: If you want compile-time guarantee that some concrete type implements some interface, use a blank variable declaration like this:
var _ UniversalError = Error3{}
The above declaration assigns a value of Error3
to a variable of type UniversalError
. Should Error3
not satisfy UniversalError
, you get a compile-time error. The above declaration will not introduce a new variable as the blank identifier was used, this is just a compile-time check.
If you would remove the Error3.CommonError1()
method:
//func (Error3) CommonError1() {}
func (Error3) UniversalError() {}
Then you would get a compile-time error right away:
./prog.go:49:5: cannot use Error3 literal (type Error3) as type UniversalError in assignment:
Error3 does not implement UniversalError (missing CommonError1 method)
来源:https://stackoverflow.com/questions/56581400/how-to-create-multi-level-error-subtypes-in-go