指针 – Golang:结构指针方法中的指针可以重新分配给另一个实例吗?

指针 – Golang:结构指针方法中的指针可以重新分配给另一个实例吗?,第1张

概述我一直在研究Golang并且已经实现了一些数据结构来学习语言的工作原理.在编写AVL树的代码时,我遇到了以下问题: 从结构指针方法分配主指针似乎在函数范围之外没有任何影响.例如. tree.rotateLeftToRoot()不会导致tree.left成为新树. 问题:有没有办法在Golang中的结构指针方法中重新指定指针,或者这通常是不鼓励的?在示例中,这将是“tree = prevLeft”行 我一直在研究Golang并且已经实现了一些数据结构来学习语言的工作原理.在编写AVL树的代码时,我遇到了以下问题:

从结构指针方法分配主指针似乎在函数范围之外没有任何影响.例如. tree.rotateleftToRoot()不会导致tree.left成为新树.

问题:有没有办法在Golang中的结构指针方法中重新指定指针,或者这通常是不鼓励的?在示例中,这将是“tree = prevleft”行.

代码段:

//Graphical representation of t.rotateleftToRoot()://      t                  L//   L     R     ->    LL     t//LL LR                     LR  Rfunc (tree *AvlTree) rotateleftToRoot() {   if tree == nil {      return   }   prevleft := tree.left   if prevleft != nil {      tree.left = prevleft.right //tree.left passed root its right branch      prevleft.right = tree      //tree becomes tree.left's right branch      tree.updateHeight()      prevleft.updateHeight()      tree = prevleft            //desired behavIoUr: tree.left becomes the new tree                                 //actual behavIoUr: no effect when function returns   }}

我已经尝试过设置树的值或地址的其他组合,但没有一个具有预期的效果.例如,* tree = * prevleft导致无限循环.

附加说明:返回树并设置“tree = tree.rotateleftToRoot()”可以避免此问题.这是有效的,但是当调用者真的只想调用函数来更新树时,混合效果并要求赋值给返回值似乎很脏.

可以从函数中将树设置为prevleft吗?

指针的值就像让我们说int数字一样.不同之处在于对该值的解释:指针被解释为内存地址,而int被解释为整数.

如果要更改int类型变量的值,则将指针传递给该类型为* int的int,并修改指向的对象:* i = newvalue(赋值的值为int).

指针也是如此:当你想要改变指针类型* int的变量的值时,你传递一个指向* int的类型为**的指针,你修改了指向的对象:* i =& newvalue(分配的值是* int).

传递指针是必需的,因为复制是从您传递的所有内容制作的,并且您只能修改副本.当你传递一个指针时,同样的事情发生了:一个副本也是由那个指针构成的,但是我们不是修改指针本身而是修改指向的值.

您想要修改* AvlTree类型的变量.在Go中,接收器不能是指向指针的指针. Spec: Method declarations:

The receiver’s type must be of the form T or *T(possibly using parentheses) where T is a type name. The type denoted by T is called the receiver base type; it must not be a pointer or interface type and it must be declared in the same package as the method.

所以你有两个选择:

>要么写一个简单的函数(不是方法),它需要一个** AvlTree,你可以传递树指针的地址,所以该函数可以修改树指针(指向的对象)
>或从函数/方法返回树指针,让调用者将其指定给作为树指针的变量.

解决有关返回树指针的问题:这没有任何问题.看看内置函数append():它将元素附加到切片并返回修改后的切片.您(调用者)必须将返回的切片分配给切片变量,因为如果附加元素不适合原始内容,append()可以通过分配新切片来修改切片(并​​且因为append()采用非指针,必须返回修改后的值).

以下是#1的解决方案如何:

func rotateleftToRoot(ptree **AvlTree) {    tree := *ptree    if tree == nil {        return    }    prevleft := tree.left    if prevleft != nil {        tree.left = prevleft.right        prevleft.right = tree        tree = prevleft    }    *ptree = tree}

我已经在Go Playground上实现了它以证明它有效.

我用过这种类型:

type AvlTree struct {    value string    left  *AvlTree    right *AvlTree}

为了便于检查结果,我实现了一些方法来生成字符串表示:

func (tree *AvlTree) String() string { return tree.str(1) }func (tree *AvlTree) str(n int) string {    if tree == nil {        return "<nil>"    }    return fmt.Sprintf("%q\n%s%v,%v\n%s",tree.value,strings.Repeat("\t",n),tree.left.str(n+1),tree.right.str(n+1),n-1))}

这就是树的构建和转换方式:

tree := &AvlTree{    value: "t",left: &AvlTree{        value: "L",left: &AvlTree{            value: "LL",},right: &AvlTree{            value: "LR",right: &AvlTree{        value: "R",}fmt.Println(tree)rotateleftToRoot(&tree)fmt.Println(tree)

原始树(没有转换):

"t"    "L"        "LL"            <nil>,<nil>,"LR"            <nil>,"R"        <nil>,<nil>

变换后的树(正是你想要的):

"L"    "LL"        <nil>,"t"        "LR"            <nil>,"R"            <nil>,<nil>
总结

以上是内存溢出为你收集整理的指针 – Golang:结构指针方法中的指针可以重新分配给另一个实例吗?全部内容,希望文章能够帮你解决指针 – Golang:结构指针方法中的指针可以重新分配给另一个实例吗?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1293773.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存