关于GO语言接口断言接收者的疑问

问题描述 投票:0回答:1
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 syntax
1个回答
0
投票

是的,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")
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.