英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论