首页 > 关于对fmt String重载的疑问

关于对fmt String重载的疑问

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),不太理解这里,求解答


两个写法是不一样的。

gofunc (h *Human) String() string { 
     fmt.Println("is run")
     return h.name + "-" + strconv.Itoa(h.age)
}

这个是 Human的指针类型的。
在定义Human实例的时候如果给的是一个指针,那么就可以

gojek := &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 来调用

【热门文章】
【热门文章】