为什么下面的Go程序需要函数的名称为String()而不是其他任何名称?

huangapple go评论85阅读模式
英文:

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.

See: https://golang.org/doc/effective_go.html#constants

huangapple
  • 本文由 发表于 2017年9月11日 11:58:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/46147978.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定