type Tt struct {
fmt.Stringer
I int
J string
}
func (t *Tt) String() string {
return fmt.Sprintf("Tt{I:%d, J:%s}", t.I, t.J)
}
func main() {
t := Tt{I: 100, J: "abc"}
fmt.Printf("%t", true)
var i any = t
v, ok := i.(fmt.Stringer)
if ok {
fmt.Printf("t --> %s", v)
} else {
fmt.Printf("t --> null")
}
}
如果将t的地址赋值给i,则真分支可以正常执行。 Go语言的接口断言是否区分接收者是否是指针类型?但接口定义忽略了接收者,这有点奇怪。 ////go版本go1.22.2 windows/amd64
是的,Go 区分了指针和值的接收者。
Effective_go#pointers_vs_values
关于接收者的指针与值的规则是,可以在指针和值上调用值方法,但只能在指针上调用指针方法。 ...
这条规则的出现是因为指针方法可以修改接收者;对值调用它们将导致该方法接收该值的副本,因此任何修改都将被丢弃。
您使用指针接收器声明了您的方法。所以您需要使用
t := &Tt{I: 100, J: "abc"}
来使用接收器。
或者,您可以使用值接收器
t := Tt{I: 100, J: "abc"}
package main
import "fmt"
type Tt struct {
fmt.Stringer
I int
J string
}
func (t Tt) String() string {
return fmt.Sprintf("Tt{I:%d, J:%s}", t.I, t.J)
}
func main() {
t := Tt{I: 100, J: "abc"}
fmt.Printf("%t", true)
var i any = t
v, ok := i.(fmt.Stringer)
if ok {
fmt.Printf("t --> %s", v)
} else {
fmt.Printf("t --> null")
}
}