猿问

接口参考显示奇怪的输出

我试图理解 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

为什么?我期望输出错误和成功,因为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引用。


catspeake
浏览 196回答 3
3回答

拉丁的传说

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包首先检查对象是否为 a Formatter、GoStringer、error或Stringer,以获取要打印的值。至于你的最后一个问题,你必须使用一个变量,而不仅仅是分配它。打印它们可以消除错误。

繁星coding

关于你的第一个问题 - 如果你添加fmt.Println(reflect.TypeOf(s))- 你会看到输出不是Succerbut *main.Combi。现在,由于它实现了Error接口并且Error() string-Println认为它是一个错误对象并打印其Error方法的输出。将Error方法更改为任何其他方法将停止Println(s)打印“错误”。但它也不会打印“成功”。

富国沪深

在您的第一个问题中,如果您想通过s调用successfunc打印成功:fmt.Println(s.Success())关于第二个问题,Go编译器检查未使用的变量,所以只分配它而不使用它显示编译错误
随时随地看视频慕课网APP

相关分类

Go
我要回答