英文:
Why does the following Go program need the function's name to be String() and not anything else?
问题
我正在遵循一本书上给出的以下示例。
package main
import (
"fmt"
)
const (
KB = 1024
MB = 1048576 //KB * 1024
GB = 1073741824 //MB * 1024
TB = 1099511627776 //GB * 1024
PB = 1125899906842624 //TB * 1024
)
type ByteSize float64
func (b ByteSize) String() string {
switch {
case b >= PB:
return "Very Big"
case b >= TB:
return fmt.Sprintf("%.2fTB", b/TB)
case b >= GB:
return fmt.Sprintf("%.2fGB", b/GB)
case b >= MB:
return fmt.Sprintf("%.2fMB", b/MB)
case b >= KB:
return fmt.Sprintf("%.2fKB", b/KB)
}
return fmt.Sprintf("%dB", b)
}
func main() {
fmt.Println(ByteSize(2048))
fmt.Println(ByteSize(3292528.64))
}
当我运行这个程序时,它给出以下输出(以人类可读的数据大小单位)。
2.00KB
3.14MB
但是,当我将名为String()的函数更改为其他任何名称,或者将String中的S小写,它给出以下输出。
2048
3.29252864e+06
这是什么原因呢?是不是有一个与某个接口相关联的String()函数,而我们的ByteSize类型满足了该接口?我的意思是什么鬼?
英文:
I'm following a book which shows the following example.
package main
import (
"fmt"
)
const (
KB = 1024
MB = 1048576 //KB * 1024
GB = 1073741824 //MB * 1024
TB = 1099511627776 //GB * 1024
PB = 1125899906842624 //TB * 1024
)
type ByteSize float64
func (b ByteSize) String() string {
switch {
case b >= PB:
return "Very Big"
case b >= TB:
return fmt.Sprintf("%.2fTB", b/TB)
case b >= GB:
return fmt.Sprintf("%.2fGB", b/GB)
case b >= MB:
return fmt.Sprintf("%.2fMB", b/MB)
case b >= KB:
return fmt.Sprintf("%.2fKB", b/KB)
}
return fmt.Sprintf("%dB", b)
}
func main() {
fmt.Println(ByteSize(2048))
fmt.Println(ByteSize(3292528.64))
}
When I run this program it gives me the following output (in human readable data size units).
2.00KB
3.14MB
But when I change the name of the function called String() to anything else, or if I lower-case the S in String, it gives me the following output.
2048
3.29252864e+06
What is the reason behind that? Is there some String() function attached to some interface and our ByteSize type satisfies that interface? I mean what the hell?
答案1
得分: 4
你的最后一句话完全正确。在Go语言中,你可以满足你甚至不知道存在的接口。你还可以为其他人的函数编写新的接口。他们的代码不需要编写"implement"、派生或其他任何东西。它完全基于函数名以及具有匹配的参数和返回值列表。
英文:
Your last sentence is exactly right. In Go, you can satisfy interfaces you didn't even know existed. And you can write new interfaces for other people's functions. Their code does not have to write "implement" or derive or anything. It is entirely based on the function name and having a matching argument and return value list.
答案2
得分: 2
当你定义一个名为String
的方法,没有参数并返回一个字符串时,你实现了Stringer
接口,该接口的文档在这里:https://golang.org/pkg/fmt/#Stringer。
英文:
When you define a method named String
with no parameters returning a string, you implement the Stringer
interface, which is documented here: https://golang.org/pkg/fmt/#Stringer.
答案3
得分: 1
这个例子与Go语言作者在《Effective Go》中的一个例子非常相似,其中描述了String()
方法的含义。
将
String()
方法附加到任何用户定义的类型上的能力使得任意值能够自动格式化自己以进行打印。尽管你经常会看到它应用于结构体,但这种技术对于诸如ByteSize之类的标量类型(如浮点类型)也很有用。
参考链接:https://golang.org/doc/effective_go.html#constants
英文:
The example is very similar to an example in "Effective Go" by the Go Authors, and the meaning of the String()
method described there.
> The ability to attach a method such as String to any user-defined type
> makes it possible for arbitrary values to format themselves
> automatically for printing. Although you'll see it most often applied
> to structs, this technique is also useful for scalar types such as
> floating-point types like ByteSize.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论