package main
import (
"fmt"
//"testpkg"
"strconv"
)
type Human struct {
name string
age int
}
func (h *Human) String() string { //此处如果修改为 Human则可以重载,如果*Human则不行
fmt.Println("is run")
return h.name + "-" + strconv.Itoa(h.age)
}
func main() {
jek := Human{"jek", 25}
fmt.Println(jek) //但是如果此处修改为 &jek就可以
}
在看书的时候写到这个例子,一开始以为是我写错,后来发现我比书上多了一个* func(h *Human),不太理解这里,求解答
两个写法是不一样的。
go
func (h *Human) String() string { fmt.Println("is run") return h.name + "-" + strconv.Itoa(h.age) }
这个是 Human的指针类型的。
在定义Human实例的时候如果给的是一个指针,那么就可以
go
jek := &Human{"jek", 25}
自我总结下吧,我加了一段判断,能够解释为什么String没有被调用,但是根本原因还是有点模糊,需要去看fmt/print.go文件
func main() {
jek := Human{"jek", 25}
fmt.Println(jek)
if _, ok := interface{}(jek).(fmt.Stringer); ok {
fmt.Printf("实现了String.\n")
} else {
fmt.Println("没有实现String")
}
//会输出“没有实现String",如果修改为interface{}(&jek)就会输出实现了
}
看另外一个问题的答案对T和*T的差别会有所了解 http://.com/q/1010000000198984
如果按照下面写, 会提示prog.go:18: method redeclared: Human.String
func (h *Human) String() string {
fmt.Println("is run")
return h.name + "-" + strconv.Itoa(h.age)
}
func (h Human) String() string {
fmt.Println("is run")
return h.name + "-" + strconv.Itoa(h.age)
}
而实际上
fmt.Println(jek)
fmt.Println(&jek)
这两个调用只会调用对应版本的String(), 编译器将 h *Human 和 h Human 视为同一类型, 但是调用的时候又分开了 h *Human 和 h Human 来调用