我正在创建一个简单的排序二叉树,它是不可变的(它应该表现得像它的不可变),我不确定指针接收器在传递带有接口(interface)的结构时如何工作。
这是我定义二叉树的方式。
type btree interface {
display(io.Writer)
add(int) btree
replace(int, int)//A test to see if we are sharing nodes
}
二叉树节点定义如下:
type node struct {
data int
left btree
right btree
}
和空的二叉树节点
type empty struct{}
功能与方法
func createEmpty() btree {
return &empty{}
}
节点结构的方法
//replace is just a test to see if I'm sharing nodes
func (n *node) replace(value, replacement int) {
if n.data < value {
n.left.replace(value, replacement)
} else if n.data > value {
n.right.replace(value, replacement)
} else {
n.data = replacement
}
}
func (n *node) add(data int) btree {
if n.data < data {
l := &node{n.data, n.left.add(data), n.right}
return l
} else if n.data > data {
r := &node{n.data, n.left, n.right.add(data)}
return r
} else {
return n
}
}
func (n *node) display(w io.Writer) {
n.left.display(w)
fmt.Fprintln(w, n.data)
n.right.display(w)
}
空节点的方法
//replace is just a test to see if I'm sharing nodes
func (*empty) replace(_, _ int) {}
func (e *empty) add(data int) btree {
en := &node{data, e, e}
return en
}
func (*empty) display(w io.Writer) {
fmt.Fprintln(w, "Empty")
}
请注意,代码确实按预期工作,但我不确定当我将带有接口(interface)成员的结构传递给指针接收器时会发生什么。接口(interface)数据结构是否被复制,但只是一个浅拷贝,所以它指向的数据保持不变?在这种情况下,是否有关于接口(interface)会发生什么的文档?
这是以下代码的工作副本:
package main
import (
"fmt"
"io"
"os"
)
func createEmpty() btree {
return &empty{}
}
type btree interface {
display(io.Writer)
add(int) btree
replace(int, int)
}
type node struct {
data int
left btree
right btree
}
func (n *node) replace(value, replacement int) {
if n.data < value {
n.left.replace(value, replacement)
} else if n.data > value {
n.right.replace(value, replacement)
} else {
n.data = replacement
}
}
func (n *node) add(data int) btree {
if n.data < data {
l := &node{n.data, n.left.add(data), n.right}
return l
} else if n.data > data {
r := &node{n.data, n.left, n.right.add(data)}
return r
} else {
return n
}
}
func (n *node) display(w io.Writer) {
n.left.display(w)
fmt.Fprintln(w, n.data)
n.right.display(w)
}
type empty struct{}
func (*empty) replace(_, _ int) {}
func (e *empty) add(data int) btree {
en := &node{data, e, e}
return en
}
func (*empty) display(w io.Writer) {
fmt.Fprintln(w, "Empty")
}
func main() {
bt := createEmpty().add(5).add(1).add(8).add(2)
bt2 := bt.add(7).add(6).add(10).add(9)
bt.display(os.Stdout)
fmt.Fprintln(os.Stdout, "\n--->")
bt2.display(os.Stdout)
fmt.Fprintln(os.Stdout, "\n\n--->")
//The node with 1 should be shared with bt and bt2
//so if we change bt's node 1 to 4143
//we should see the change in bt2 too
bt.replace(1, 4143)
bt.display(os.Stdout)//We see the change here, 1 is now 4143
fmt.Fprintln(os.Stdout, "\n--->")
bt2.display(os.Stdout)//We see the change here, 1 is now 4143
}
最佳答案
鉴于这种结构:
type node struct {
data int
left btree
right btree
}
和函数
f
使用 q 指针接收器:func (n *node) f() {}
f
获得指向 node
的指针.任何更改f
使节点 n
将反射(reflect)在用于调用 f
的副本上.更准确地说,当您调用
n.f()
如果 n
是 *node
,然后将该指针的副本发送到 f
,它仍然指向与 n
相同的对象.如果 n
不是指针,则&n
将发送至f
.为了让您的代码正常工作,左右
btree
接口(interface)还应该包含 *node
s,而不是 node
s(你已经正确地做到了)。这是因为,例如,如果您调用 node.left.replace
,您想要 node.left
中的值将被替代。如果您有 replace
的值接收器函数,那么当你调用 node.left.replace
该左节点的副本将被发送到 replace
用作接收器,修改在 node.left
上不可见节点。希望这可以帮助。
关于go - 具有接口(interface)成员和指针接收器的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59706822/