首页 > 解决方案 > syscall.Errno 中的字符串函数

问题描述

通读“Go 编程语言”的 7.8 部分,我发现了以下代码:

var err error = syscall.Errno(2)
fmt.Println(err.Error()) // "no such file or directory"
fmt.Println(err)         // "no such file or directory"

我理解第一行和第二行。error接口由 满足syscall.Errno,因此Error()函数返回string可用。

第三个没看懂 浏览syscall's sources我找不到任何syscall.Errno满足stringer接口的地方 -String()未定义功能。

为什么第三个打印字符串表示sysscall.Errno

标签: go

解决方案


答案可在此处fmt的文档中找到:

如果格式(对于 Println 等隐含 %v)对字符串(%s %q %v %x %X)有效,则适用以下两条规则:

  1. 如果操作数实现了错误接口,则会调用 Error 方法将对象转换为字符串,然后根据动词(如果有)的要求对其进行格式化。

  2. 如果操作数实现方法 String() 字符串,则将调用该方法将对象转换为字符串,然后根据动词(如果有)的要求对其进行格式化。

所以实际上,对于同时支持两者的任何值,该String()方法根本不会被调用,因为error接口优先于Stringer接口。您可以使用这样的程序进行测试

package main

import (
    "fmt"
)

type foo string

func (f foo) String() string {
    return "string"
}

func (f foo) Error() string {
    return "error"
}

func main() {
    fmt.Println(foo(""))
}

输出:

error

推荐阅读