英文:
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()
}
还有一堆问题
- 为什么我不能写:append(namers, p)?&p 是指向 P 的指针,而 namers 数组不是指针数组。
- 为什么 TypeOf(namers[0]) 是 *P 而 TypeOf(on) 是 *Namer?这没有意义,TypeOf(&(*P)) 应该是 **P。
- 为什么最后一行打印的是 "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
- Why I cannot write: append(namers, p)? &p is a pointer to P, array namers is not a array of pointers
- Why TypeOf(namers[0]) is *P and TypeOf(on) is *Namer? It does not make sense, TypeOf(&(*P)) should be **P
- 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
-
P没有实现接口Namer,只有P实现了,因为PrintName()是在P上定义的。
-
据我理解,TypeOf(namers[0])是*P,因为你正在检查实际的切片元素本身,并且TypeOf可以查看接口的内部。而TypeOf(&namers[0])只是取第一个元素的地址并检查其类型(当然,namers是一个Namer接口元素的切片),而不是实际地“内部”查看元素本身。
-
最后一行没有打印任何内容,因为(**on).Name是不允许的。将其更改为(*on).(*P).Name = "EEEE",它将按预期工作。
英文:
-
P doesn't implement interface Namer, only *P does, as PrintName() is defined on *P.
-
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.
-
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论