类型、接口和指针

huangapple go评论110阅读模式
英文:

Types, interfaces and pointers

问题

我有一个简单的代码:

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()
}

还有一堆问题 类型、接口和指针

  1. 为什么我不能写:append(namers, p)?&p 是指向 P 的指针,而 namers 数组不是指针数组。
  2. 为什么 TypeOf(namers[0]) 是 *P 而 TypeOf(on) 是 *Namer?这没有意义,TypeOf(&(*P)) 应该是 **P。
  3. 为什么最后一行打印的是 "Name" 而不是 "EEE"?

谢谢帮助!

英文:

I have a simple code:

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()
}

and bunch of questions 类型、接口和指针

  1. Why I cannot write: append(namers, p)? &p is a pointer to P, array namers is not a array of pointers
  2. Why TypeOf(namers[0]) is *P and TypeOf(on) is *Namer? It does not make sense, TypeOf(&(*P)) should be **P
  3. Why the last line print: "Name" instead of "EEE"?

Thanks for help!

答案1

得分: 1

断言*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
英文:

Assert that *on is of type *P. For example,

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()
}

Output:

<pre>
*main.P
*main.Namer
Name
EEEE
</pre>

答案2

得分: 0

我想 - 请记住我并不是非常精通GO语言 - 你提出所有问题的主要原因与你以一种使接收者(实现者)对象为指针的方式实现了PrintName方法有关。

英文:

I suppose - bear in mind I am not really proficient in GO - that the main reason for all of your questions is related to the fact that you implemented PrintName in a way that the receiver (implementer) object is a pointer.

答案3

得分: 0

  1. P没有实现接口Namer,只有P实现了,因为PrintName()是在P上定义的。

  2. 据我理解,TypeOf(namers[0])是*P,因为你正在检查实际的切片元素本身,并且TypeOf可以查看接口的内部。而TypeOf(&namers[0])只是取第一个元素的地址并检查其类型(当然,namers是一个Namer接口元素的切片),而不是实际地“内部”查看元素本身。

  3. 最后一行没有打印任何内容,因为(**on).Name是不允许的。将其更改为(*on).(*P).Name = "EEEE",它将按预期工作。

英文:
  1. P doesn't implement interface Namer, only *P does, as PrintName() is defined on *P.

  2. As I understand it, TypeOf(namers[0]) is *P because you're inspecting the actual slice element itself, and TypeOf can see inside the interface. With TypeOf(&namers[0]) you're merely taking the address of the first element and inspecting its type (which is, of course, *Namer, as namers is a slice of Namer interface elements), without actually looking "inside" the element itself.

  3. The last line doesn't print anything, because (**on).Name is not allowed. Change it to (*on).(*P).Name = "EEEE" and it works as intended.

huangapple
  • 本文由 发表于 2015年5月9日 19:10:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/30139200.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定