【问题标题】:Stringer interface with int type具有 int 类型的 Stringer 接口
【发布时间】:2017-10-15 19:13:56
【问题描述】:

我刚刚通过 Tour of Go 学习了 golang 语言,并达到了 Stringer 部分。 (https://tour.golang.org/methods/17)

我试图了解它是如何工作的,所以我尝试了 int tpye。它没有用。

代码:

package main

import (
    "fmt"
)

type I int

func (i I) String() string {
    return fmt.Sprintf("%v", i)
}

func main() {   
    i := I(10)
    fmt.Println(i)
}

当我运行示例时,我遇到了一个错误,我不太明白什么是探针。

我的理论是使用 String() 方法: 当我运行打印机代码时,程序会查找 stringer 方法,如果存在则运行它。 它是这样工作的?

谁能向我解释一下这到底是如何工作的?

错误(在围棋巡回赛中):

runtime: goroutine stack exceeds 250000000-byte limit
fatal error: stack overflow

runtime stack:
runtime.throw(0xff4a2, 0xe)
    /usr/local/go/src/runtime/panic.go:605 +0x100
runtime.newstack(0x0, 0x0)
    /usr/local/go/src/runtime/stack.go:1050 +0x960
runtime.morestack()
    /usr/local/go/src/runtime/asm_amd64p32.s:378 +0xa0

goroutine 1 [running]:
runtime.mallocgc(0x4, 0xef280, 0x18500300, 0x0, 0x0, 0x0)
    /usr/local/go/src/runtime/malloc.go:581 +0xb60 fp=0x18500360 sp=0x18500358 pc=0x31440
runtime.convT2E32(0xef280, 0x185003a4, 0x83cc0, 0x10)
    /usr/local/go/src/runtime/iface.go:247 +0x80 fp=0x18500380 sp=0x18500360 pc=0x2e000
main.I.String(0xa, 0x185003d0, 0x185003d4, 0x0)
    /tmp/sandbox580986616/main.go:10 +0x40 fp=0x185003b8 sp=0x18500380 pc=0xd4f60
main.(*I).String(0x1391de68, 0x11d050, 0x13972a80, 0xef280)
    <autogenerated>:1 +0x40 fp=0x185003d0 sp=0x185003b8 pc=0xd51c0
fmt.(*pp).handleMethods(0x13972a80, 0x76, 0x1, 0x0)
    /usr/local/go/src/fmt/print.go:596 +0x3a0 fp=0x18500420 sp=0x185003d0 pc=0xcdf60
fmt.(*pp).printArg(0x13972a80, 0xef280, 0x1391de68, 0x76)
    /usr/local/go/src/fmt/print.go:679 +0x1a0 fp=0x18500468 sp=0x18500420 pc=0xce540
fmt.(*pp).doPrintf(0x13972a80, 0xfe0ce, 0x2, 0x18500560, 0x1, 0x1)
    /usr/local/go/src/fmt/print.go:996 +0x180 fp=0x18500508 sp=0x18500468 pc=0xd32c0
fmt.Sprintf(0xfe0ce, 0x2, 0x18500560, 0x1, 0x1, 0x0, 0x0, 0x0)
    /usr/local/go/src/fmt/print.go:196 +0x60 fp=0x18500538 sp=0x18500508 pc=0xca160
main.I.String(0xa, 0x18500588, 0x1850058c, 0x0).......

【问题讨论】:

  • 错误是什么??
  • 讽刺的是,堆栈溢出。

标签: go


【解决方案1】:

你的问题很简单。您将I 类型的值传递给fmt.Println,它调用Is String 方法,该方法使用I 类型的值调用fmt.Sprintf,该方法调用Is String 方法。 ..

只需将Is String 方法的主体更改为:return fmt.Sprintf("%v", int(i)) 就可以了。

【讨论】:

  • 你能解释一下为什么没有运行代码吗?为什么 sprintf 不吃接口类型?
  • 或者你可以在 String 方法中使用 fmt.Sprintf("%d", i)
  • I 不是 int。它可能是一个int,但fmt 不知道这一点。它可以找出它是否愿意,但如果它这样做了,那么它根本不会调用您的String 方法。 String 接收到 I 类型的值,因此在您的 String 方法中调用 fmt.Sprintf 就像在 main 中调用 fmt.Println 一样完全。
  • 是的,%d 也可以。问题是要远离fmt.Sprintf,不要将调用(I).String 视为一种选择。
【解决方案2】:
fmt.Sprintf("%v", i)

在Sprintf方法中,会调用i的string(),而i的string调用这个fmt.Sprintf(),所以栈溢出。

【讨论】:

    猜你喜欢
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 2014-05-07
    • 2023-03-08
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多