golang 中嵌入式类型的内部状态 - 它是如何工作的?
Inner state of embedded types in golang - how does it work?
我正在努力思考如何嵌入到 golang 中,但当涉及到嵌入到另一个类型中的类型的状态时,我有点困惑。
这是我的问题:如果我有一个 Embedii
类型,它是一个 int,并且它有一个影响其值的方法,它应该出现在嵌入它的类型中吗?
这是我正在玩的东西:
package main
import (
"fmt"
)
type Embedii int
func (y *Embedii) Do() {
if y == nil {
y = new(Embedii)
} else {
*y = *y + 1
}
fmt.Println(*y)
}
type Embedder struct {
*Embedii
}
func main() {
embedii := new(Embedii)
embedii.Do() // prints 1
embedii.Do() // prints 2
fmt.Println("---")
embedder := new(Embedder)
embedder.Do() // prints 0
embedder.Do() // prints 0
fmt.Println("---")
nembedii := new(Embedii)
embedo := &Embedder{nembedii}
embedo.Do() // prints 1
embedo.Do() // prints 2
}
https://play.golang.org/p/ArqKESVWoS-
我很想知道为什么我必须明确地将 Embedii
的现有实例传递给 Embedder
类型才能正常工作
在Embedii.Do()
中接收者是一个指针值。这是一个副本。向该指针变量分配任何内容只会修改副本。
y = new(Embedii)
只是给局部变量y
赋了一个指针,当Do()
returns的时候,就丢失了。再次调用时,y
将再次成为 nil
,因此它会为其创建并分配一个新值(在 returning 后将再次丢失)。
如果您先创建一个 Embedii
,它会起作用,因为那样您就不会在 Do()
中创建和分配它(这会丢失)。
如果你 return 新的 Embedii
(更准确地说是它的地址)并分配它,你会看到它递增,但它将以 0
而不是 1
,因为第一次调用只是创建它而没有递增,而在其他情况下它已经存在,所以第一次调用立即递增:
func (y *Embedii) Do() *Embedii {
if y == nil {
y = new(Embedii)
} else {
*y = *y + 1
}
fmt.Println(*y)
return y
}
并使用它:
embedder := new(Embedder)
embedder.Embedii = embedder.Do() // prints 0
embedder.Embedii = embedder.Do() // prints 1
输出将是(在 Go Playground 上尝试):
1
2
---
0
1
---
1
2
"should that appear in a type that embeds it?" 是的,它应该是,因为它是结构中的另一种类型。
我正在努力思考如何嵌入到 golang 中,但当涉及到嵌入到另一个类型中的类型的状态时,我有点困惑。
这是我的问题:如果我有一个 Embedii
类型,它是一个 int,并且它有一个影响其值的方法,它应该出现在嵌入它的类型中吗?
这是我正在玩的东西:
package main
import (
"fmt"
)
type Embedii int
func (y *Embedii) Do() {
if y == nil {
y = new(Embedii)
} else {
*y = *y + 1
}
fmt.Println(*y)
}
type Embedder struct {
*Embedii
}
func main() {
embedii := new(Embedii)
embedii.Do() // prints 1
embedii.Do() // prints 2
fmt.Println("---")
embedder := new(Embedder)
embedder.Do() // prints 0
embedder.Do() // prints 0
fmt.Println("---")
nembedii := new(Embedii)
embedo := &Embedder{nembedii}
embedo.Do() // prints 1
embedo.Do() // prints 2
}
https://play.golang.org/p/ArqKESVWoS-
我很想知道为什么我必须明确地将 Embedii
的现有实例传递给 Embedder
类型才能正常工作
在Embedii.Do()
中接收者是一个指针值。这是一个副本。向该指针变量分配任何内容只会修改副本。
y = new(Embedii)
只是给局部变量y
赋了一个指针,当Do()
returns的时候,就丢失了。再次调用时,y
将再次成为 nil
,因此它会为其创建并分配一个新值(在 returning 后将再次丢失)。
如果您先创建一个 Embedii
,它会起作用,因为那样您就不会在 Do()
中创建和分配它(这会丢失)。
如果你 return 新的 Embedii
(更准确地说是它的地址)并分配它,你会看到它递增,但它将以 0
而不是 1
,因为第一次调用只是创建它而没有递增,而在其他情况下它已经存在,所以第一次调用立即递增:
func (y *Embedii) Do() *Embedii {
if y == nil {
y = new(Embedii)
} else {
*y = *y + 1
}
fmt.Println(*y)
return y
}
并使用它:
embedder := new(Embedder)
embedder.Embedii = embedder.Do() // prints 0
embedder.Embedii = embedder.Do() // prints 1
输出将是(在 Go Playground 上尝试):
1
2
---
0
1
---
1
2
"should that appear in a type that embeds it?" 是的,它应该是,因为它是结构中的另一种类型。