Go 类型、接口和指针

Go 类型、接口和指针,go,Go,我有一个简单的代码: type Namer interface { PrintName() } type P struct { Name string } func (p *P) PrintName() { fmt.Printf("%s\n", p.Name) } func main() { p := P{Name: "Name"} var namers []Namer namers = append(namers, &p)

我有一个简单的代码:

type Namer interface {
    PrintName()
}

type P struct {
    Name string
}

func (p *P) PrintName() {
    fmt.Printf("%s\n", p.Name)
}

func main() {
    p := P{Name: "Name"}

    var namers []Namer
    namers = append(namers, &p)
    fmt.Println(reflect.TypeOf(namers[0]))

    on := &namers[0]
    fmt.Println(reflect.TypeOf(on))
    (*on).PrintName()
    (**on).Name = "EEEE"
    (*on).PrintName()
}
还有一大堆问题:)

  • 为什么我不能写:append(namers,p)&p是指向p的指针,数组名称不是指针数组
  • 为什么TypeOf(namers[0])是*P而TypeOf(on)是*Namer?没有意义,TypeOf(&(*P))应该是**P
  • 为什么最后一行打印“Name”而不是“EEE”

  • 谢谢你的帮助

    我想——请记住,我对围棋并不十分精通——你所有问题的主要原因都与你实现
    PrintName
    的方式有关,即接收者(实现者)对象是指针。

    断言
    *on
    的类型是
    *p
    。比如说,

    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    type Namer interface {
        PrintName()
    }
    
    type P struct {
        Name string
    }
    
    func (p *P) PrintName() {
        fmt.Printf("%s\n", p.Name)
    }
    
    func main() {
        p := P{Name: "Name"}
    
        var namers []Namer
        namers = append(namers, &p)
        fmt.Println(reflect.TypeOf(namers[0]))
    
        on := &namers[0]
        fmt.Println(reflect.TypeOf(on))
        (*on).PrintName()
        (*on).(*P).Name = "EEEE"
        (*on).PrintName()
    }
    
    输出:

    *main.P *main.Namer Name EEEE *main.P *主叫 名称 EEEE
  • p不实现接口名称,只有*p实现,因为PrintName()是在*p上定义的

  • 据我所知,TypeOf(namers[0])是*p,因为您正在检查实际的slice元素本身,TypeOf可以在接口内部看到。使用TypeOf(&namers[0]),您只需获取第一个元素的地址并检查其类型(当然是*Namer,因为namers是Namer接口元素的一部分),而不实际查看元素本身的“内部”

  • 最后一行没有打印任何内容,因为不允许使用(**on).Name。将其更改为(*on)。(*P).Name=“EEEE”即可按预期工作


  • 不。将其更改为
    func(p)PrintName()后,
    rest保持不变。