为什么Golang打印错误而不是字符串?

问题描述 投票:0回答:1

我正在查看 Go“A Tour of Go”中的示例,其中我尝试了错误示例。因此,我对其进行了一些修改,并期望得到不同的结果。

package main

import (
    "fmt"
    "time"
)

type MyStruct struct {
    When time.Time
    What string
}

func (e MyStruct) Error() string {
    return fmt.Sprintf("######### %v, %s", e.When, e.What)
}

func (e MyStruct) String() string {
    return fmt.Sprintf("******** %v", e.When)
}

func run() MyStruct {
    return MyStruct{
        time.Now(),
        "it didn't work",
    }
}

func main() {
    obj := run()
    fmt.Println(obj)
}

这里我期待 main() 中的

fmt.Println(obj)
应该打印

******** 2009-11-10 23:00:00 +0000 UTC 米=+0.000000001

但是正在打印。

########## 2009-11-10 23:00:00 +0000 UTC m=+0.000000001,它不起作用

go error-handling
1个回答
5
投票

在 golang fmt.Println 中,在

Error()
方法之前考虑
Stringer
方法。当您在类型上实现了
Error
String
方法时,它将首先打印
Error
方法中的内容。

fmt文档中,以

Except when printed using the verbs %T and %p

开头的部分
4. If an operand implements the error interface, the Error method will be invoked to convert the object to a string, which will then be formatted as required by the verb (if any).

5. If an operand implements method String() string, that method will be invoked to convert the object to a string, which will then be formatted as required by the verb (if any). 

代码参考:handleMethods

....

case 'v', 's', 'x', 'X', 'q':
    // Is it an error or Stringer?
    // The duplication in the bodies is necessary:
    // setting handled and deferring catchPanic
    // must happen before calling the method.
    switch v := p.arg.(type) {
    case error:
        handled = true
        defer p.catchPanic(p.arg, verb, "Error")
        p.fmtString(v.Error(), verb)
        return

    case Stringer:
        handled = true
        defer p.catchPanic(p.arg, verb, "String")
        p.fmtString(v.String(), verb)
        return
    }
....
        

© www.soinside.com 2019 - 2024. All rights reserved.