英文:
Golang Pointers as method param
问题
我正在使用golang的指针,就像我在C++中做的那样,但似乎不起作用,哪种方法是正确的?或者我做错了什么?谢谢。
我正在进行AsyncBinaryTrees。
type Obj interface {
Compare(node Obj) int
}
type Tree struct {
Item Obj
Right, Left *Tree
height int16
}
func Insert(t *Tree, item Obj) chan struct{} {
done := make(chan struct{}, 1)
go insert(t, item, done)
return done
}
func insert(t *Tree, item Obj, done chan struct{}) {
if t == nil {
t = &Tree{Item: nil, Right: nil, Left: nil, height: 0}
var signal struct{}
done <- signal
close(done)
} else {
if t.Item.Compare(item) == 1 { //Left
insert(t.Left, item, done)
} else if t.Item.Compare(item) == -1 { //Right
insert(t.Right, item, done)
} else {
close(done)
panic
}
}
}
//=== testing
func assertSignal(ch_signal chan struct{}, t *testing.T) {
_, done := <-ch_signal
if !done {
t.Error("Error: it should send a signal of empty struct")
}
}
func TestInsertion(t *testing.T) {
var tree *Tree
ch_signal := Insert(tree, newObjInt())
fmt.Println(t) //=> <nil>
assertSignal(ch_signal, t) //=> PASS
ch_signal = Insert(tree, newObjInt())
fmt.Println(t) //=> <nil>
assertSignal(ch_signal, t) //=> PASS
ch_signal = Insert(tree, newObjInt())
fmt.Println(t) //=> <nil>
assertSignal(ch_signal, t) //=> PASS
ch_signal = Insert(tree, newObjInt())
assertSignal(ch_signal, t) //=> PASS
}
nil
nil
nil
测试通过
英文:
I am working with golang's pointers the way I did with c++, but it seems not to work, which would be the right way to do it? or what am I doing wrong?, Thanks.
ftw I'm doing AsyncBinaryTrees.
type Obj interface {
Compare(node Obj) int
}
type Tree struct {
Item Obj
Rigth, Left *Tree
height int16
}
func Insert(t *Tree, item Obj) chan struct{} {
done := make(chan struct{}, 1)
go insert(t, item, done)
return done
}
func insert(t *Tree, item Obj, done chan struct{}) {
if t == nil {
t = &Tree{Item: nil, Rigth: nil, Left: nil, height: 0}
var signal struct{}
done <- signal
close(done)
} else {
if t.Item.Compare(item) == 1 { //Left
insert(t.Left, item, done)
} else if t.Item.Compare(item) == -1 { //Rigth
insert(t.Right, item, done)
} else {
close(done)
panic
}
}
}
//=== testing
func assertSignal(ch_signal chan struct{}, t *testing.T) {
_, done := <-ch_signal
if !done {
t.Error("Error: it should send a signal of empty struct")
}
}
func TestInsertion(t *testing.T) {
var tree *Tree
ch_signal := Insert(tree, newObjInt())
fmt.PrintLn(t) //=> <nil>
assertSignal(ch_signal, t) //=>PASS
ch_signal = Insert(tree, newObjInt())
fmt.PrintLn(t) //=> <nil>
assertSignal(ch_signal, t) //=>PASS
ch_signal = Insert(tree, newObjInt())
fmt.PrintLn(t) //=> <nil>
assertSignal(ch_signal, t) //=>PASS
ch_signal = Insert(tree, newObjInt())
assertSignal(ch_signal, t) //=>PASS
}
nil
nil
nil
TEST PASS
答案1
得分: 3
在你的insert函数中,你有以下代码:
func insert(t *Tree, item Obj, done chan struct{}) {
if t == nil {
t = &Tree{Item: nil, Rigth: nil, Left: nil, height: 0}
...
}
这段代码更新了局部变量t,但不会改变在调用范围内传递的变量,因为Go通过值传递函数参数。所以当你进行以下调用时:
insert(t.Left, item, done)
如果t.Left是nil,它的值不会被函数调用改变。如果你确实希望它更新变量,你需要将函数参数定义为t **Tree,将引用更改为设置*t,并将调用更改为:
insert(&t.Left, item, done)
在Go中没有类似于C++通过引用传递函数参数的语法:相反,你需要在传递指针时明确指定。
英文:
In your insert function you have:
func insert(t *Tree, item Obj, done chan struct{}) {
if t == nil {
t = &Tree{Item: nil, Rigth: nil, Left: nil, height: 0}
...
}
This updates the local variable t, but will not change the variable passed in the calling scope since Go passes function parameters by value. So when you make the following call:
insert(t.Left, item, done)
if t.Left is nil, its value will not be changed by the function call. If you do want it to update the variable, you'll need to define the function argument as t **Tree, change references to set *t instead, and change the call to:
insert(&t.Left, item, done)
There is no equivalent to C++'s syntax for passing function arguments by reference: instead you need to be explicit when passing pointers.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论