Go 中的格式错误 - %s %v 或 %w

2024-04-30

%s %v and %w可用于格式化 Go 中的错误(将它们转换为字符串)fmt.Errorf).

它们在 Go 自己的工具中的使用方式似乎有所不同。

In cmd/go/internal/get/path.go https://github.com/golang/go/blob/1fb7d5472e8f46faaa034fe6e16ca66a1e7c766f/src/cmd/go/internal/get/path.go#L26:

return fmt.Errorf("malformed import path %q: %v", path, err)

In cmd/go/internal/list/list.go https://github.com/golang/go/blob/6a9d850b82172225b55bd65e830b1e325b17a724/src/cmd/go/internal/list/list.go#L355:

base.Fatalf("%s", err)

我应该使用哪种格式字符串?


我应该使用 %s 还是 %v 来格式化错误?

TL;DR;两者都不。使用%w在 99.99% 的情况下。在另外 0.001% 的情况下,%v and %s可能“应该”表现相同,除非错误值为nil,但没有任何保证。更友好的输出%v for nil错误可能是选择的理由%v(见下文)。

现在详细介绍:

Use %w代替%v or %s:

从 Go 1.13 开始(或者更早版本,如果您使用golang.org/x/xerrors https://godoc.org/golang.org/x/xerrors),您可以使用%w动词,仅用于error值,它包装错误,以便稍后可以使用errors.Unwrap https://golang.org/pkg/errors/#Unwrap,因此可以考虑errors.Is https://golang.org/pkg/errors/#Is and errors.As https://golang.org/pkg/errors/#As.

唯一不合适的时候:

  1. 您必须支持旧版本的 Go,并且xerrors不是一个选择。
  2. 您想要创建一个独特的错误,并且not包装现有的一个。这可能是合适的,例如,如果您得到Not found搜索用户时数据库出错,并且希望将其转换为Unauthorized回复。在这种情况下,您很少会使用原始错误值any不过,格式化动词。

好吧,那又怎样呢%v and %s?

具体如何操作%s and %v已实施 可用在文档中 https://golang.org/pkg/fmt/#hdr-Printing。我已经突出显示了与您的问题相关的部分。

  1. 如果操作数是reflect.Value,则操作数将被它所保存的具体值替换,并继续打印下一条规则。

  2. 如果操作数实现了 Formatter 接口,它将被调用。格式化程序提供对格式化的精细控制。

  3. 如果 %v 动词与 # 标志 (%#v) 一起使用并且操作数实现 GoStringer 接口,则将调用该接口。

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

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

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

总而言之,fmt.*f函数将:

  1. 寻找一个Format()方法,如果存在,他们会调用它。
  2. 寻找一个Error()方法,如果存在,他们会调用它。
  3. 寻找一个String()方法,如果存在,则调用它。
  4. 使用一些默认格式。

所以在实践中,这意味着%s and %v是相同的,除了当Format()方法存在于错误类型上(或者当错误是nil)。当错误确实存在时Format()方法,人们可能希望它能产生与%s, %v, and err.Error(),但由于这取决于错误的实现,因此无法保证,因此这里没有“正确答案”。

最后,如果您的错误类型支持%+v动词变体,那么如果您想要详细的输出,您当然需要使用它。

nil values

虽然很少(故意)打电话fmt.*f on a nil错误,行为确实有所不同%s and %v:

%s: %!s(<nil>)
%v: <nil>

游乐场链接 https://play.golang.org/p/mZYuJof6KQY

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go 中的格式错误 - %s %v 或 %w 的相关文章

  • Golang中按长度分割字符串

    有谁知道如何在 Golang 中按长度分割字符串 例如 每 3 个字符分割 helloworld 那么理想情况下它应该返回一个 hel low orl d 数组 或者 一个可能的解决方案是在每 3 个字符后附加一个换行符 所有的想法都非常感
  • Golang:带有 JSON 负载的 http.NewRequest POST 返回错误 500

    我正在开发一个 API 库 有一个API端点 POST 当您发出curl命令时 它是 curl H X API TOKEN API TOKEN http interest graph getprismatic com text topic
  • 带有用户信息的 Django Logger

    我只是好奇 是否可以放User内的信息formatters信息输入LOGGING配置在setting py 现在我只是将该信息放入要记录的消息中 但也许有一种方法可以将其设置为formatters争论 这是我的LOGGING现在的配置 LO
  • XSL字符串多重替换功能

    如何让这个函数进行多重替换 经验 替换aaa with 111并替换bbb with 222 etc
  • 直接从一个通道发送到另一个通道

    当从一个通道直接发送到另一个通道时 我偶然发现了令人惊讶的行为 package main import fmt func main my chan make chan string chan of chans make chan chan
  • .join() 方法到底是做什么的?

    我对 Python 还很陌生 并且完全困惑 join 我读过的是连接字符串的首选方法 I tried strid repr 595 print array array c random sample string ascii letters
  • 返回类型时 c_str() 与 data()

    在C 11之后 我想到了c str and data 同等地 https stackoverflow com questions 194634 string c str vs data C 17 为后者引入了一个重载 它返回一个非常量指针
  • os.Mkdir 和 os.MkdirAll 权限

    我正在尝试在程序开始时创建一个日志文件 我需要检查是否 log如果不创建目录 则目录存在 然后继续创建日志文件 好吧 我尝试使用os Mkdir 也os MkdirAll 但无论我在第二个参数中输入什么值 我都会得到一个没有权限的锁定文件夹
  • 如何从 JavaScript 中的字符串中删除空白字符?

    如何从 JavaScript 中的字符串中删除空白字符 修剪很容易 但我不知道如何将它们从inside字符串 例如 222 334 gt 222334 您可以使用正则表达式 如下所示来替换所有空格 var oldString 222 334
  • unordered_map 中字符串的 C++ 哈希函数

    看起来 C 标准库中没有字符串的哈希函数 这是真的 在任何 c 编译器上使用字符串作为 unordered map 中的键的工作示例是什么 C STL提供模板专业化 http en cppreference com w cpp string
  • 如何关闭 gorm 1.20.0 中的数据库实例

    由于我没有在 Close 函数中找到 gorm 实例 任何帮助将不胜感激 dbURI fmt Sprintf user s password s dbname s port s sslmode s TimeZone s username p
  • 在 Gorilla Mux 中嵌套子路由器

    我一直在使用gorilla mux https github com gorilla mux满足我的路由需求 但我注意到一个问题 当我嵌套多个子路由器时它不起作用 这是示例 func main r mux NewRouter StrictS
  • 获取字符串中的最后一个整数

    我需要隔离包含多个整数的字符串中最新出现的整数 我怎样才能得到23代替1 for lastnum1 text 1 out of 23 lastnum1 this gt getEval eregi replace out of text 你可
  • Python - 将宽字符字符串从二进制文件转换为 Python unicode 字符串

    这是漫长的一天 我有点困惑 我正在读取一个包含大量宽字符字符串的二进制文件 我想将它们转储为 Python unicode 字符串 为了解压非字符串数据 我使用 struct 模块 但我不知道如何对字符串执行相同的操作 例如 阅读 系列 一
  • 在 Go 中,如何将结构体转换为字节数组?

    我有一个我定义的结构实例 我想将其转换为字节数组 我尝试了 byte my struct 但这不起作用 另外 我还被指出二进制包 http golang org pkg encoding binary 但我不确定我应该使用哪个函数以及应该如
  • 改变字符串颜色

    好的 这是我上一个问题的延续 但我有代码 private void btnTrans Click object sender EventArgs e var abrvStr inputBx Text foreach var kvp in d
  • 如何将接口转换为接口切片?

    我的输入是interface 而且我知道它可以是任何类型的数组 我想读取我输入的元素之一 所以我尝试将我的interface 进入一个 interface 但是 go 会给我以下错误 恐慌 接口转换 interface 是 map stri
  • 将文本拆分为数组,同时保留 Swift 中的标点符号

    我想将文本拆分为一个数组 保持标点符号与其余单词分隔开 因此字符串如下 Hello I am Albert Einstein 应该变成这样的数组 Hello I am Albert Einstein 我尝试过sting components
  • WPF:将布尔值显示为“是”/“否”

    我有一个布尔值 需要在 TextBlock 中显示为 是 或 否 我尝试使用 StringFormat 执行此操作 但我的 StringFormat 被忽略并且 TextBlock 显示 True 或 False
  • 根据列中的部分字符串匹配选择数据框行

    我想根据列中字符串的部分匹配从数据框中选择行 例如列 x 包含字符串 hsa 使用sqldf if它有一个like语法 我会做类似的事情 select from lt gt where x like hsa 很遗憾 sqldf不支持该语法

随机推荐

  • d3.js 和 Chart.js 之间的比较(仅适用于图表)[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我在项目中多次使用过 Chart js 但从未使用过 d3 js 很多人说 d3 js 是最好的图表 javascript 框架 但没
  • 如何获取 Highcharts 中某个点的索引?

    我正在使用 Highcharts 的 具有不规则间隔的时间数据 图表 如您所知 当鼠标移动到线条点上时 格式化程序函数将运行并显示一些信息 我想知道鼠标在其上移动的点的索引 因此 如果鼠标移动到该线的第一个点上 工具提示将显示 1 第二个点
  • 为什么不能直接访问带索引的数组?

    当我尝试直接使用索引访问数组元素时 我感到很困惑 我想我可以在编码中更好地解释它 我有一个 Employee 类的对象 我将其 TypeCast 到数组并尝试像这样显示它 arrOfObj array objEmployee arrKeys
  • windows bat 文件中的 bang 字符是什么意思?

    我正在尝试更正一个使用 bang 字符的 bat 文件 我本来期望某种形式的引用 就像是 set some var some var 然后后来 some command some var 看起来第一个是在禁用回显的情况下提示输入 例如提示输
  • Django 压缩器和模板继承

    我正在使用Django 压缩器 https github com mintchaos django compressorDjango 1 2 3 中的 app 用于缩小和合并许多包含的 CSS 和 JS 文件 在基本模板中 我有 load
  • Java中如何让另一个线程休眠

    我有一个扩展 Thread 的类 这个线程在运行时大部分时间都在睡眠 它会执行一个检查 如果 true 执行一个简单的操作 然后睡眠 1 2 秒并重复 该类还有一个由其他线程调用的公共方法 如果调用此函数 我希望线程在已经休眠的情况下休眠更
  • 比较 boost::system::error_category

    对于 errorCode category name 输出 asio misc 和 errorCode message 输出 文件结束 的错误 以下比较失败 如果它声称属于 asio misc 类别 那么为什么 errorCode cate
  • MediaProjection 生成扭曲的屏幕截图

    我设法获得了屏幕截图 但结果是这样的 原来的 这是我从几个来源获取的代码 final ImageReader ir ImageReader newInstance width height PixelFormat RGBA 8888 2 V
  • 如何在 linux bash shell 中对字符串数组进行排序? [复制]

    这个问题在这里已经有答案了 例如 数组是 link2 pathname link1 pathname link3 pathname 我怎样才能得到像下面这样的数组 link1 pathname link2 pathname link3 pa
  • 如何在 R 中将包含符号的绘图写入 PDF?

    我想在 R 中的箱形图的 x 轴上使用无穷大符号 我想将其写入 PDF 文件 我可以通过这样做来设置无穷大符号 names data 9 lt 但这让我在尝试编写时出现编码错误 conversion failure on in mbcsTo
  • 在QT中以不同的时间间隔更新GUI [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想知道如何在QT中以不同的时间间隔更新GUI 最好的是我可以控制时间间隔 我知道 QTimer 可以在同一时间间隔更新 GUI 但我
  • Angular 2.0.0-rc3:与 routerLinkActive 匹配的部分路由

    我在用着routerLinkActive在我的主要路由中 a Bob a 当网址为 user the active类将被添加到a标签 但是在主路由下 我还有一些辅助路由 所以 当网址为 user aa 活动将被删除 我希望当 URL 是 u
  • Joda-time:今年 ISO 第一周的第一天

    我想找出今年 ISO 第 1 周中星期一的日期 对于 2009 年 这将是 2008 年 12 月 29 日星期一 我确定乔达时间 http www joda org joda time cal iso html可以处理这个问题 但我就是无
  • 如何使用 Laravel 5 检查用户是否已确认

    我正在尝试开箱即用地使用 Laravel 身份验证 身份验证不是问题 但我想检查用户是否已确认他的电子邮件地址 我如何让拥有Laravel检查表值是否confirmed值为 1 在 config auth php 我已经设置 driver
  • RecyclerView 的弹跳效果

    我想在RecyclerView 每当我过度滚动内容时就会出现反弹效果 是否有一个库或示例 我也找不到任何支持 RecyclerView 弹跳效果的库 最终我自己实现了一个新的库 查看我的图书馆过度滚动弹力 android https git
  • 从 Ruby 中的方法中检索 Method 实例

    这是一个后续问题如何确定方法是在哪个类中定义的 https stackoverflow com q 34742181 477037 希望你不要介意相似之处 给定一个类层次结构 一个方法可以检索自己的方法吗 Method实例 class A
  • 代理错误:无法将请求 /auth/register 从 localhost:3000 代理到 http://localhost:8800/api/

    注册 jsx import React from react import useState from react import Link from react router dom import axios from axios cons
  • selenium.common.exceptions.SessionNotCreatedException:消息:未从选项卡创建的会话使用 ChromeDriver Chrome Selenium Python 崩溃

    当我尝试访问脚本请求的没有特定的 url 时 显然出现此错误 我不明白为什么会出现这个错误 但我想对其进行处理 以免在发生错误时中止脚本 这会重复 但不能解决我的问题 如何避免错误 selenium common exceptions Se
  • 如何在 swift 中实现 Pubnub Access Manager

    我正在研发如何在 swift 中实现 pubnub 访问管理器 经过一些研究 我了解到 Swift SDK 不包含 pubnub grant 我需要使用 pubnub 函数来实现无服务器计算 我在 pubnub 仪表板中创建了一个函数并创建
  • Go 中的格式错误 - %s %v 或 %w

    s v and w可用于格式化 Go 中的错误 将它们转换为字符串 fmt Errorf 它们在 Go 自己的工具中的使用方式似乎有所不同 In cmd go internal get path go https github com go