【发布时间】:2016-01-25 10:34:17
【问题描述】:
原来的问题
我有以下 Go 代码。我想将Foo 结构或Bar 类型作为字符串处理。对于“句柄”,我的意思是我想将/转换/任何它的底层值转换为(真实)类型string。我有一个解决方法,但我发现在结构的情况下它不直观。
选择类型(而不是结构)似乎是更好的方法。我不需要维护任何状态,也不需要“继承”特定于类型的功能,所以在我的情况下它应该可以工作。然而,调用type.String() 会导致堆栈递归。如果我没有遗漏什么(很明显),我主要是好奇。
package main
import "fmt"
type Foo struct {
string
}
func (f *Foo) String() string {
return f.string
}
type Bar string
func (b *Bar) String() string {
return fmt.Sprintf("%s", b) // Cannot use: return string(b) here.
}
func main() {
a := Foo{"a"}
var b Bar
b = "b"
fmt.Printf("A is: %s\n", a) // Doesn't call a.String() ?
//fmt.Printf("A is: %s\n", string(a)) // Doesn't work
fmt.Printf("A is: %s\n", a.string) // workaround A
fmt.Printf("A is: %s\n", a.String()) // workaround B, required if I want to use it in a different package
fmt.Printf("B is: %s\n", b) // Calls b.String()
fmt.Printf("B is: %s\n", string(b))
//fmt.Printf("B is: %s\n", b.String()) // Causes a stack overflow
}
输出:
A is: {a}
A is: a
A is: a
B is: b
B is: b
Go 游乐场代码:https://play.golang.org/p/zgrKao4cxa 该行为来自 Go 版本 1.5.2
答案
以下是基于我最初问题的答案的简短示例。此外,以下帖子有助于理解和推理该主题:Value receiver vs. Pointer receiver in Golang?
在类型的情况下,以下工作:
type MyString string
func (b MyString) String() string {
return string(b)
}
Go 的游乐场链接:https://play.golang.org/p/H12bteAk8D
在结构的情况下,以下工作:
package main
import "fmt"
type MyString struct {
string
someState int
}
func (m MyString) String() string {
return string(m.string)
}
func main() {
// The verbose version:
//var a MyString = MyString{string: "a", someState: 1}
a := MyString{"a", 1}
fmt.Printf("A is: %s\n", a)
fmt.Printf("A is: %s\n", a.String())
}
Go 的 Playground 链接:https://play.golang.org/p/GEKeY4rmB8
【问题讨论】:
-
b 的 String() 函数可以使用
return string(*b),不需要 sprintf 的值。只需要匹配函数的返回类型 -
啊,你是对的。我不敢相信我错过了。我想我被错误消息
cannot convert b (type *Bar) to type string吓跑了。感谢您的帮助。 -
@Dynom 请不要为您的问题添加答案。如果您有一些有趣的信息要分享,请在下方添加您自己的答案。
标签: go