英文:
Why does switch match a different type in below code sample in golang
问题
链接:
https://play.golang.org/p/69I8PAuoAV
提取:
package main
import "fmt"
type Stringer interface {
String() string
}
type fakeString struct {
content string
}
// 用于实现Stringer接口的函数
func (s *fakeString) String() string {
return s.content
}
func printString(value interface{}) {
switch str := value.(type) {
case string:
fmt.Println(str)
case Stringer:
fmt.Println(str.String())
}
}
func main() {
s := &fakeString{"Ceci n'est pas un string"}
printString(s)
printString("Hello, Gophers")
}
当调用printString(s)
函数时,它匹配到了case Stringer
部分。
s
的类型是*fakeString
而不是Stringer
。
为什么它匹配到了Stringer
?
我使用了fmt.Println(reflect.TypeOf(str))
,它确认了类型为*main.fakeString
。
英文:
Link:
https://play.golang.org/p/69I8PAuoAV
Extract:
package main
import "fmt"
type Stringer interface {
String() string
}
type fakeString struct {
content string
}
// function used to implement the Stringer interface
func (s *fakeString) String() string {
return s.content
}
func printString(value interface{}) {
switch str := value.(type) {
case string:
fmt.Println(str)
case Stringer:
fmt.Println(str.String())
}
}
func main() {
s := &fakeString{"Ceci n'est pas un string"}
printString(s)
printString("Hello, Gophers")
}
The printString(s)
function call when reaching case matches the case Stringer
part.
s
is of type *fakeString
not Stringer
.
Why does it match Stringer
.
I did a fmt.Println(reflect.TypeOf(str))
and it confirmed the type as *main.fakeString
答案1
得分: 4
在Go语言中,要满足一个接口,你只需要实现该接口的方法,没有其他要求。在这个例子中,为了具有Stringer的行为,你需要实现String() string
方法,因此类型fakeString表现得像一个Stringer,因为它实现了该方法;从面向对象编程的角度来看,我们使用接口只是为了定义行为,而不是类型或值。所以你可能在不知情的情况下整天都在实现Go接口,但这并不重要,只有在需要满足特定行为时才会有影响。
实际上,在一个真实的项目中,你可能希望在printString
方法的switch语句中添加一个default
情况,以便检测接口{}是其他类型的情况,像这样:
func printString(value interface{}) {
switch str := value.(type) {
case string:
fmt.Println("string", str)
case Stringer:
fmt.Println("Stringer", str.String())
default:
fmt.Printf("unexpected type: %T value: '%v'", str, str)
}
}
// main:
printString(2)
链接:https://play.golang.org/p/pmxSXfUu4e
英文:
In Go to satisfy an interface all you have to do is implement the methods of that interface nothing else. In this case to have a behavior as a Stringer you have to implement String() string
, so the type fakeString behaves as a Stringer because implement that method; in terms of OOP we use interfaces just to define behavior not types or values. So you may be implementing Go interfaces all day without knowing, but not big deal, it only matters when you have to satisfy behaviors.
Actually in a real project you may want to add a default
case to your switch in the method printString
, to detect when the interface{} is something else, like this:
func printString(value interface{}) {
switch str := value.(type) {
case string:
fmt.Println("string", str)
case Stringer:
fmt.Println("Stringer", str.String())
default:
fmt.Printf("unexpected type: %T value: '%v'", str, str)
}
}
// main:
printString(2)
答案2
得分: 1
这是关于golang中的接口满足性。
在golang中有两种类型:接口类型和具体类型。
具体类型
在switch
语句中的行为与你期望的完全一致:变量是给定类型的实例。- 另一方面,
接口类型
的行为不同,它检查变量是否满足接口的要求。
嗯,满足?它是如何工作的呢?
> 如果(具体)类型拥有接口所需的所有方法,则该类型满足该接口。
>
> -- golang编程语言
在这种情况下,Stringer
是一个接口,只声明了一个方法:String() string
。而fakeString
通过拥有自己的String() string
方法来满足它。
然而需要注意两点:
- 具体类型可以有许多其他方法,只要它拥有接口中声明的所有方法,它仍然满足该接口。
- 方法的顺序无关紧要,重要的是方法的集合。
英文:
This is interface satisfaction in golang.
There are two kinds of type in golang: interface type and concrete type.
concrete type
works exactly as you expected inswitch
: the variable is an instance of the given typeinterface type
on the other hand works differently, it checks if the variable satisfies the interface.
Hum, safisfies? How does it work?
> A (concrete) type satisfies an interface if it possesses all the methods the interface requires.
>
> -- the golang programming language
In the case, Stringer
is an interface, declaring only one method: String() string
. And fakeString
satisfies it by having its own String() string
method.
Two things to note however:
- concrete type can have many other methods, it still satisfies the interface if it possesses all methods declared in interface
- the methods order does not matter, all that matters is the set of methods.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论