Error 方法内的 fmt.Sprint(e) 产生的无限循环

2024-01-21

根据四十四十的回复这个问题 https://stackoverflow.com/questions/27474907/error-infinite-loop:

fmt.Sprint(e)将会通知e.Error()转换值e to a string。如果Error()方法调用fmt.Sprint(e),那么 程序会递归直到内存不足。

您可以通过转换来打破递归e到一个没有a的值String or Error method.

这仍然让我感到困惑。为什么 fmt.Sprint(e) 调用 e.Error() 而不是 String()?我尝试使用 Stringer 接口,这是我的代码:

package main

import (
  "fmt"
  "math"
)

type NegativeSqrt float64

func (e NegativeSqrt) Error() string {
  fmt.Printf(".")
  return fmt.Sprint(e)
}

func (e NegativeSqrt) String() string {
  return fmt.Sprintf("%f", e)
}

func Sqrt(x float64) (float64, error) {
  if x < 0 {
    return 0, NegativeSqrt(x)
  }
  return math.Sqrt(x), nil
}

func main() {
  fmt.Println(Sqrt(2))
  fmt.Println(Sqrt(-2))
}

看来已经解释了directly https://github.com/golang/go/blob/2ed57a8cd86cec36b8370fb16d450e5a29a9375f/src/pkg/fmt/print.go#L639是 fmt 包的来源:

// Is it an error or Stringer?
// The duplication in the bodies is necessary:
// setting handled and deferring catchPanic
// must happen before calling the method.

然后Error() http://golang.org/src/fmt/print.go?s=6663:6699#L714 or String() http://golang.org/src/fmt/print.go?s=6663:6699#L720叫做。

这句话的意思就是首先错误.Error() http://golang.org/pkg/builtin/#error调用以生成字符串,然后再次处理该字符串并将其打印为字符串。

Whether error有方法String在这里无关紧要。问题是为什么NegativeSqrt使用一种方法打印,而不使用另一种方法打印。类型NegativeSqrt两者都实现fmt.Stringer and error接口,所以它取决于实现fmt封装应该使用哪个接口来获取string from NegativeSqrt (since fmt.Sprint http://golang.org/src/fmt/print.go?s=6663:6699#L237其参数为interface{}).

为了说明这一点,请考虑以下示例:

package main

import (
    "fmt"
)

type NegativeSqrt float64

func (e NegativeSqrt) Error() string {
    return ""
}

func (e NegativeSqrt) String() string {
    return ""
}

func check(val interface{}) {
    switch val.(type) {
    case fmt.Stringer:
        fmt.Println("It's stringer")
    case error:
        fmt.Println("It's error")
    }
}

func check2(val interface{}) {
    switch val.(type) {
    case error:
        fmt.Println("It's error")
    case fmt.Stringer:
        fmt.Println("It's stringer")
    }
}

func main() {
    var v NegativeSqrt
    check(v)
    check2(v)
}

执行此命令给出:

% go run a.go
It's stringer
It's error

这是因为在 Go 中类型 switch 的行为就像普通 switch 一样,所以案件顺序很重要 https://golang.org/doc/effective_go.html#switch.

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

Error 方法内的 fmt.Sprint(e) 产生的无限循环 的相关文章

  • Goroutine 是如何工作的? (或者:goroutines 和操作系统线程的关系)

    其他 goroutine 如何在调用系统调用时继续执行 当使用 GOMAXPROCS 1 时 据我所知 当调用系统调用时 线程会放弃控制权 直到系统调用返回 Go 如何在不为每个阻塞系统调用 goroutine 创建系统线程的情况下实现这种
  • 将 Websocket 消息发送到 Go 中的特定通道(使用 Gorilla)

    我对 Go 很陌生 并且发现自己使用套接字作为我的第一个项目 这是一个多余的问题 但我无法理解如何将 websocket 更新发送到 Go 中的特定通道 使用 Gorilla 我在用此链接中的代码示例 https github com go
  • 无法从另一个标签的源代码构建和安装 go

    我正在尝试使用此从源代码构建和安装 go文档 https go dev doc install source 当我喜欢以下内容时 这效果很好 git clone https go googlesource com go goroot cd
  • 无法将字符串解组为 int64 类型的 Go 值

    我有结构 type tySurvey struct Id int64 json id omitempty Name string json name omitempty I do json Marshal在 HTML 页面中写入 JSON
  • K8s更改配置映射并更新应用程序日志级别

    我想更改在 K8S 上运行的 Golang 应用程序的登录配置 我在本地尝试了以下代码 它按预期工作 我正在使用 viper 来监视配置文件更改 这是带有日志配置的配置图 apiVersion v1 kind ConfigMap data
  • golang导入结构体指针

    好的 我有一个主包和一个 http 处理程序包 本质上我想做的是设置一个全局结构 这样我就可以随时调用该结构中的信息 我尝试的示例的基本概要如下 主包导入处理函数 主包调用handlerfunc Handlerfunc 将 http Res
  • 将 []string 传递给需要可变参数的函数

    为了不一遍又一遍地重复我的自我 我想创建一个处理运行一些命令的函数 func runCommand name string arg string error cmd exec Command name arg if err cmd Run
  • Google App Engine Golang 没有这样的文件或目录

    我正在用 Go 开发一个 Google App Engine 项目 并陷入了读取文件的困境 事实上 应用程序在本地运行得很好 然而 部署时 它会恐慌告诉我没有这样的文件或目录 这是我的 fileValue 方法 func fileValue
  • Golang、mysql:错误1040:连接过多

    我正在使用 github com go sql driver mysql 驱动程序 我打开一个数据库 db err sql Open mysql str 然后我有两个函数 每个函数被调用 200 次 并使用以下 mysql 代码 rows
  • Bazel 构建缺少严格的依赖关系

    我正在尝试使用 brazel 构建 Go 应用程序 它是一个现有的私有 GitHub 存储库 位置如下 github xyz com repo name 我正在研究 我的目标是从 main go 文件创建一个二进制文件 该文件的方法依赖于其
  • 当变量更新时动态刷新模板的一部分golang

    在Golang中 当变量更新时可以刷新模板的一部分吗 例如 我们可以在 Angular js 中找到这一点 基本上在我的代码中 我通过 ajax 中的邮政编码查找地址 它显示我找到的该邮政编码的用户列表 Here is a sample o
  • 如何在 Visual Studio Code 中为 Golang 启用竞争检测器?

    我搜索了很多网页来找到我应该放入哪个短语settings json在 VS Code Golang 扩展 由 Microsoft 发布 中添加构建标志 在我的例子中是竞赛检测器 I added go buildFlags race 在扩展名
  • Go MSSQL 连接

    如何提供 MSSQL 连接 它说它始终与代码相关 即使信息不正确 也不会报错 package main import database sql fmt github com denisenkom go mssqldb log var ser
  • 如何在 Go 中表示可选字符串?

    我希望建模一个可以有两种可能形式的值 不存在或字符串 执行此操作的自然方法是Maybe String or Optional
  • 使用 crypto/ssh 的 golang scp 文件

    我正在尝试通过 ssh 下载远程文件 以下方法在 shell 上运行良好 ssh hostname tar cz opt local folder gt folder tar gz 然而 golang 上的相同方法在输出工件大小方面存在一些
  • nsq 无法通过连接到 nsqlookupd 来消费消息

    我尝试使用 docker compose 来运行 nsq docker compose yml如下 version 3 services nsqlookupd image nsqio nsq command nsqlookupd ports
  • 在函数中将通道作为参数传递的不同方法

    我正在阅读一些Go代码 并说了几种传递Go通道的不同方法 也许它们是相同的 但我想知道是否有任何区别 因为我无法在线找到文档 1 func serve ch lt chan interface do stuff 2 func serve c
  • 在 IntelliJ IDEA 中运行。多个文件和错误未定义:数据

    我想使用 IntelliJ IDE 社区版编写代码GO Go语言 我安装了正确的插件 并安装了构建应用程序所需的所有工具 我的应用程序包含以下两个文件 每个都在目录中 事件服务器 Main go Data go 如果我想使用 Run Ctl
  • Gorm 总是返回带有 nil 值的结构

    我正在使用 Gorm 构建 Go Web API 作为 Amazon RDS 中 Postgresql 数据库的 ORM 问题是 Gorm 总是返回一片结构 其值全部为零 尽管数据库已经填充了数据 切片中的结构体数量是否合适取决于LIMIT
  • 重新插入通道导致死锁

    我有稳定的入站 作业 流 将其输入到无缓冲通道中 我有一个for range循环来迭代项目并处理它们 如果处理该项目失败 我会将项目重新插入通道中 以便稍后重试 问题是当我将项目重新插入通道时 它陷入僵局 我明白为什么会发生这种情况 处理器

随机推荐

  • jQuery UI:类型错误:$(...).accordion 不是函数

    由于某种原因jQuery UI 手风琴不起作用 我不断收到此错误 类型错误 accordion 不是函数 我究竟做错了什么 根据本网站上类似主题的其他答案 我认为这与包含的文件有关 我的标题包括
  • 让 div 在屏幕上移动

    我需要让一个彩色 div 水平向右移动 当它到达边缘时 它的大小应该加倍 绕中心旋转的速度应该是两倍 var topPosition 50 var leftPosition 250 var rightPosition 800 functio
  • ClickOnce 更新时会删除我的本地数据库。如何不删除?

    我正在使用 ClickOnce 来部署我的应用程序 当应用程序第一次运行时 如果数据库不存在 它会创建一个 问题是 当我更新时 它会删除本地数据库 有没有办法告诉它忽略它 我想你把它放在应用程序目录中 不要 把它放进去Environment
  • 如何使用 Worklight 传输媒体文件

    使用 Worklight 适配器传输媒体 照片或电影 的正确方法是什么 我通过适配器发送照片并收到错误 表格太大 超出最大尺寸 我读到我需要通过 Jetty 更改表单大小 但我将部署应用程序的服务器不会是码头 那么我要做什么 shell 呢
  • Java 中的 Kerberos 身份验证 - java 中的“登录”操作是否等于“kinit”?

    我在 Java 中使用 GSSAPI 以便使用 Kerberos 身份验证登录到 LDAP 服务器 我是 Kerberos 的新手 所以如果这是一个明显的问题 我很抱歉 但我在互联网上找不到足够清晰的内容 我执行以下步骤 通过设置系统属性定
  • 同一个套接字上可以进行多少个异步套接字请求?

    当我在套接字上调用 BeginSend 时 我传递一个委托 该委托将在数据发送后 由不同的线程 调用 如果我在第一次尚未 回调 时再次调用 BeginSend 会发生什么 发送数据的正确行为是什么 执行 BeginSend 然后在回调中执行
  • linux 上的 Dart 抛出错误:GLIBC_2.14 GLIBC_2.15 not found

    我在 Google Compute Engine 上运行 Debian 7 2 尽管我怀疑 Centos Red Hat 和 Amazon Linux AMI 都有同样的问题 从 下载 64 位 Linux 版本的 Dart SDK 后这一
  • Gunicorn 工作线程和线程

    就 Gunicorn 而言 我知道有各种工作线程类 但对于本次对话 我只关注同步和异步类型 据我了解 sync workers 2 cpu 1 worker class sync async gevent workers 1 worker
  • 当我期望它输出 1,2,3 时,为什么此代码输出“49,50,51”

    package com company import java util Scanner public class Main public static void main String args System out println pl
  • 在 Docker Alpine 上安装 numpy

    我正在尝试在基于 Alpine 3 1 的 docker 容器中安装 numpy 我正在使用以下 Dockerfile FROM alpine 3 1 RUN apk add update make cmake gcc g gfortran
  • 如何使用 alembic --autogenerate 忽略某些模式

    我有一个图书馆 它是一个更大项目的一部分 该库在与较大项目共享的 PostgreSQL 数据库中使用自己的模式 我想用alembic revision autogenerate仅生成库架构的迁移并忽略对主 默认架构中表的更改 有什么选择可以
  • Zebra LP2844 停止响应 ZPL 命令或文件

    我向打印机发送了几个 zpl 文件来测试它 它工作得很好 之后 我从 UPS 接收 Base64 编码的 zpl 数据 创建一个文件并通过 Java 小程序将其发送到打印机 现在我发送给它的任何 zpl 命令或文件都不起作用 我将其置于诊断
  • MVC Core 如何强制/设置所有操作的全局授权?

    如何强制 设置 MVC Core 中所有操作的全局授权 我知道如何注册全局过滤器 例如我有 Setup cs services AddMvc options gt options Filters Add new RequireHttpsAt
  • 学说无关系连接[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以在不使用关系的情况下连接 ORM 中的表 https stackoverflow com questions 2203027 is this possible to join tables i
  • Golang gin gonic Web框架代理路由到另一个后端

    如何将一些路由的代理 Web 请求反向到另一个后端杜松子酒 https gin gonic github io gin Golang 网络框架 有没有办法直接在Handle函数中转发如下图 router gin New router Han
  • maven中package和groupId有什么区别

    我了解这些条款 groupId artifactId and version 在阅读有关package 我可以看到它是您的根包的名称 默认值是groupId你之前进入过 在这种情况下 有什么区别package and groupId 我想它
  • Magento 1.9 - OroCRM 更新同步无法正常工作

    从 magento 1 9 更改客户详细信息后 更改未反映在 OroCRM 上几乎 2 天后仍然没有更改未反映在 OroCRM 上 如何同时在每个更改中进行自动同步 None
  • 无法使用 UPDATE 更改 MySQL 上的用户密码

    在 MySql 5 7 17 下 上述指令不起作用 并且我总是没有收到任何反馈或以下错误消息 错误 1064 42000 您的 SQL 语法有错误 检查与您的 MySQL 服务器版本相对应的手册 了解在 UPDATE mysql user
  • 如何使用 ps -axl 查找 Linux 上运行的 Java 线程?

    我有一个正在运行的 JVM 有两个线程 是否可以使用 ps axl 在我的 Linux 操作系统上查看这些正在运行的线程 我试图找出操作系统赋予我的线程的优先级 有关此其他问题的更多信息here https stackoverflow co
  • Error 方法内的 fmt.Sprint(e) 产生的无限循环

    根据四十四十的回复这个问题 https stackoverflow com questions 27474907 error infinite loop fmt Sprint e 将会通知e Error 转换值e to a string 如