Go 接口引用显示奇怪的输出
我试图理解Go的接口概念,并创建以下代码:Go 接口引用显示奇怪的输出,go,Go,我试图理解Go的接口概念,并创建以下代码: package main import "fmt" type Failer interface { Error() string } type Succer interface { Success() string } type Result interface { Failer Succer } type Fail struct{} func (*Fail) Error() string { ret
package main
import "fmt"
type Failer interface {
Error() string
}
type Succer interface {
Success() string
}
type Result interface {
Failer
Succer
}
type Fail struct{}
func (*Fail) Error() string {
return "Error"
}
type Succ struct{}
func (*Succ) Success() string {
return "Success"
}
type Combi struct{}
func (*Combi) Error() string {
return "Error"
}
func (*Combi) Success() string {
return "Success"
}
func main() {
var r Result
var s Succer
c := &Combi{}
r = c
s = c
fmt.Println(r.Error())
fmt.Println(s)
}
作为我的输出
Error
Error
为什么??我希望输出为error和success,因为s
它是Succer类型的接口,没有作为字符串返回的错误。
当我像这样改变主函数时:
func main() {
var r Result
var s Succer
c := &Combi{}
r = c
s = c
}
编译器抱怨
# command-line-arguments
.\sample1.go:42: r declared and not used
.\sample1.go:43: s declared and not used
为什么??我给变量
r
和s
分配了一个参考。关于您的第一个问题-如果您添加fmt.Println(reflect.TypeOf(s))
,您将看到输出不是sucker
,而是*main.Combi
现在,由于它实现了Error
接口,并且具有Error()字符串-Println
认为它是一个go Error对象,并打印其Error
方法的输出
将Error
方法更改为任何其他方法将停止打印“Error”。但是它也不会打印“Success”。关于你的第一个问题,如果你添加fmt.Println(reflect.TypeOf(s))
,你会看到输出不是Succer
,而是*main.Combi
现在,由于它实现了Error
接口,并且具有Error()字符串-Println
认为它是一个go Error对象,并打印其Error
方法的输出
将Error
方法更改为任何其他方法将停止打印“Error”。但是它也不会打印“Success”。fmt。Println(s)
打印“Error”,因为Error
在fmt
包中是特殊情况
switch v := p.arg.(type) {
case error:
handled = true
defer p.catchPanic(p.arg, verb)
p.printArg(v.Error(), verb, depth)
return
case Stringer:
handled = true
defer p.catchPanic(p.arg, verb)
p.printArg(v.String(), verb, depth)
return
}
}
fmt
包首先检查对象是否是格式化程序
、GoStringer
、错误
或字符串
,以获得要打印的值
至于你的最后一个问题,你必须使用一个变量,而不仅仅是赋值。打印它们将删除错误。fmt。Println(s)
打印“错误”,因为error
在fmt
包中是特殊情况
switch v := p.arg.(type) {
case error:
handled = true
defer p.catchPanic(p.arg, verb)
p.printArg(v.Error(), verb, depth)
return
case Stringer:
handled = true
defer p.catchPanic(p.arg, verb)
p.printArg(v.String(), verb, depth)
return
}
}
fmt
包首先检查对象是否是格式化程序
、GoStringer
、错误
或字符串
,以获得要打印的值
至于你的最后一个问题,你必须使用一个变量,而不仅仅是赋值。打印它们将删除错误。在第一个问题中,如果要使用s
打印成功,请调用success
func:
fmt.Println(s.Success())
关于第二个问题,Go
compiler检查未使用的变量,因此在第一个问题中只分配它而不使用它显示编译错误,如果要使用s
打印成功,请调用success
func:
fmt.Println(s.Success())
关于第二个问题,Go
编译器检查未使用的变量,所以只分配它而不使用它显示编译错误