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

我试图理解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 {
    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
编译器检查未使用的变量,所以只分配它而不使用它显示编译错误