为了账号安全,请及时绑定邮箱和手机立即绑定

打印忽略“String() 字符串”方法的 Go 类型

打印忽略“String() 字符串”方法的 Go 类型

Go
回首忆惘然 2021-08-16 19:52:08
如果我有这样的类型:type myType ...func (m myType) String() string { ... }如何fmt使用默认表示(即,而不是String()调用)打印(使用各种函数)这种类型?我想做的是这样的:func (m myType) String() string {    // some arbitrary property    if myType.isValid() {        // format properly    } else {        // will recurse infinitely; would like default        // representation instead        return fmt.Sprintf("invalid myType: %v", m)    }}
查看完整描述

3 回答

?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

fmt.Stringer 是默认格式,在您使用%v. 如果您想要 Go 语法,请使用%#v.


或者,您可以fmt完全绕过反射,并按照您认为合适的方式格式化输出。


func (m myType) String() string {

    return fmt.Sprintf("{Field: %s}", m.Value)

}

如果 myType 的底层类型是数字、字符串或其他简单类型,则在打印时转换为底层类型:


func (m mType) String() string {

    return fmt.Sprint(int(m))

}


查看完整回答
反对 回复 2021-08-16
?
缥缈止盈

TA贡献2041条经验 获得超4个赞

使用%#v代替%v

那不会调用 String()。- 但如果你实现它,它会调用GoString ()。


查看完整回答
反对 回复 2021-08-16
?
慕后森

TA贡献1802条经验 获得超5个赞

%#v如果您想让基础类型String工作或您的类型是类型别名,则使用格式不是正确的答案。


如Effective Go 中所述,只需将其转换回它所代表的类型:


type Foo int


func (f Foo) String() string {

    if f == 0 {

        return "foo"

    }

    return fmt.Sprintf("%v", int(f)) // N.B.

}


func main() {

    fmt.Println(Foo(0))

    fmt.Println(Foo(42))

}


编辑:正如其他人在评论中指出的那样,如果您的类型是结构,%#v那么除了将其转换为具有相同字段的匿名结构类型之外,使用格式似乎是唯一的方法。


查看完整回答
反对 回复 2021-08-16
  • 3 回答
  • 0 关注
  • 268 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信