Golang指针作为方法参数

huangapple go评论100阅读模式
英文:

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 = &amp;Tree{Item: nil, Rigth: nil, Left: nil, height: 0}
var signal struct{}
done &lt;- 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 := &lt;-ch_signal
if !done {
t.Error(&quot;Error: it should send a signal of empty struct&quot;)
}
}
func TestInsertion(t *testing.T) {
var tree *Tree
ch_signal := Insert(tree, newObjInt())
fmt.PrintLn(t)             //=&gt; &lt;nil&gt;
assertSignal(ch_signal, t) //=&gt;PASS
ch_signal = Insert(tree, newObjInt())
fmt.PrintLn(t)             //=&gt; &lt;nil&gt;
assertSignal(ch_signal, t) //=&gt;PASS
ch_signal = Insert(tree, newObjInt())
fmt.PrintLn(t)             //=&gt; &lt;nil&gt;
assertSignal(ch_signal, t) //=&gt;PASS
ch_signal = Insert(tree, newObjInt())
assertSignal(ch_signal, t) //=&gt;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.Leftnil,它的值不会被函数调用改变。如果你确实希望它更新变量,你需要将函数参数定义为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 = &amp;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(&amp;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.

huangapple
  • 本文由 发表于 2014年5月2日 13:12:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/23421203.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定