dongliyan7318 2016-09-27 18:13
浏览 129
已采纳

struct String()实现导致带有Sprintf“ +”标志的堆栈溢出

Golang noob question: Why can I not use the "%+v" flag for a struct in the String() implementation method?

I have a struct where I want to implement a String() method for pretty print. I like the answer given here, but I don't like to type, so I'm trying to modify it to return a string using the "%+v" format flag for structs. from the fmt doc:

%v the value in a default format when printing structs, the plus flag (%+v) adds field names

This works fine if I simply call it with fmt.Printf("%+v", color), but if I try to put the + flag in the String() implementation, I get a stack overflow (my first chance to ask a "stack overflow" question on stackoverflow.com ;) )

I'm sure I'm not understanding a pointer reference here, or there is some recursion. I doubt this noob found my first Golang bug, so can someone please explain?

see go play demonstration here https://play.golang.org/p/13_qI8Iwwa

  • 写回答

1条回答 默认 最新

  • doufei9805 2016-09-27 18:26
    关注

    See Package fmt Docs:

    Except when printed using the verbs %T and %p, special formatting considerations apply for operands that implement certain interfaces. In order of application:

    1. 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).

    To avoid recursion in cases such as

    type X string 
    func (x X) String() string { return Sprintf("<%s>", x) }
    

    convert the value before recurring:

    func (x X) String() string { return Sprintf("<%s>", string(x)) }
    

    Infinite recursion can also be triggered by self-referential data structures, such as a slice that contains itself as an element, if that type has a String method. Such pathologies are rare, however, and the package does not protect against them.


    Inside:

    func (c Color) String() string {
        // THIS CAUSES STACK OVERFLOW
        return fmt.Sprint(c)
    }
    

    The call to

    fmt.Sprint(c)
    

    or fmt.Println(c) which calls func (c Color) String() string again recursively causes overflow: try it on The Go Playground


    Also this works fine: https://play.golang.org/p/NYLtrxUeiA

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥65 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?