接口引用显示奇怪的输出

huangapple go评论81阅读模式
英文:

Interface reference shows weird output

问题

我正在尝试理解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",因为sSuccer类型的接口,没有返回错误字符串的方法。当我将main函数改成以下形式时:

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

为什么会这样呢?我给变量rs赋了一个引用。

英文:

I am trying to understand Go's interface concept and create following code:

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)
}

As output I've got

Error 
Error

Why? I've expect as output error and success, because s it is the interface of type Succer, there is no error return as string.
And when I change the main function like this:

func main() {

	var r Result
	var s Succer

	c := &Combi{}
	r = c
    s = c

}

the compiler complain

# command-line-arguments
.\sample1.go:42: r declared and not used
.\sample1.go:43: s declared and not used

Why? I assign variables r and s a reference.

答案1

得分: 3

fmt.Println(s) 打印出"Error",因为errorfmt包中是特殊处理的。

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包首先检查对象是否为FormatterGoStringererrorStringer,按照这个顺序获取要打印的值。

至于你最后一个问题,你必须使用一个变量,而不仅仅是赋值。打印它们会消除错误。

英文:

fmt.Println(s) prints "Error" because error is special-cased in the fmt package

		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
		}
	}

The fmt package first checks if an object is a Formatter, GoStringer, error, or Stringer , in that order, to obtain a value to print.

As for your last question, you have to use a variable, not just assign it. Printing them removes the error.

答案2

得分: 2

关于你的第一个问题 - 如果你添加 fmt.Println(reflect.TypeOf(s)) - 你会发现输出不是 Succer 而是 *main.Combi

现在,由于它实现了 Error 接口并且有 Error() string 方法 - Println 认为它是一个 Go 错误对象并打印其 Error 方法的输出。

Error 方法更改为其他任何内容将阻止 Println(s) 打印 "Error"。但它也不会打印 "Success"。

英文:

Regarding your first question - if you add fmt.Println(reflect.TypeOf(s)) - you'll see that the output is not Succer but *main.Combi.

Now, since it implements the Error interface and has Error() string- Println thinks it's a go error object and prints the output of its Error method.

Changing the Error method to anything else will stop Println(s) from printing "Error". But it won't print "Success" either.

答案3

得分: 0

在你的第一个问题中,如果你想用s调用一个success函数来打印成功:

fmt.Println(s.Success())

至于第二个问题,Go编译器会检查未使用的变量,所以只是赋值而没有使用会显示编译错误。

英文:

In your first question, if you want to print success with s call a success func:

fmt.Println(s.Success())

About the second question, Go compiler check unused variables, so only assign it without use it show compilation error

huangapple
  • 本文由 发表于 2015年3月17日 23:26:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/29103107.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定