【问题标题】:Nested struct is not updated嵌套结构未更新
【发布时间】:2019-01-20 06:46:27
【问题描述】:

我有一个嵌套结构。我想在一个方法中更新它。 由于某种原因,更新不会发生。

    package main

    import "fmt"

    type B struct {
        c int
    }

    type A struct {
        b B
    }

    func (a A) updateB(n int) {
        a.b.c = n
    }

    func main() {
        a := A{b: B{c: 5}}

        fmt.Println(a)
        a.updateB(42)
        fmt.Println(a)
    }

我得到的输出是

{{5}}
{{5}}

在大多数语言中,我希望它会更新。这是一些特殊的 Go 行为吗?在 Go 中如何更新嵌套结构?

【问题讨论】:

    标签: go


    【解决方案1】:

    这是因为您正在使用值接收器,因此 updateB 方法接收到的值是 A 的副本,而不是指向包含 a 变量的内存的指针。使用指针接收器解决了这个问题:

    package main
    
    import "fmt"
    
    type B struct {
        c int
    }
    
    type A struct {
        b B
    }
    
    func (a *A) updateB(n int) {
        a.b.c = n
    }
    
    func main() {
        a := A{b: B{c: 5}}
    
        fmt.Println(a)
        a.updateB(42)
        fmt.Println(a)
    }
    

    https://play.golang.org/p/XBrxd246qT3

    另见:

    Value receiver vs. Pointer receiver in Golang?

    【讨论】:

      【解决方案2】:

      这不是因为结构是嵌套的,而是因为您需要一个指针接收器来修改接收器指向的值,在这种情况下是您的a 变量。

      如果没有指针,您的 UpdateB 方法只会更新原始 A 结构值的副本。

      请参阅以下内容:

      package main
      
      import "fmt"
      
      type B struct {
          c int
      }
      
      type A struct {
          b B
      }
      
      func (a *A) UpdateB(n int) {
          a.b.c = n
      }
      
      func main() {
          a := A{b: B{c: 5}}
      
          fmt.Println(a)
          a.UpdateB(50)
          fmt.Println(a)
      }
      

      【讨论】:

        【解决方案3】:

        问题在于您的更新功能。您应该将其添加到指向 A 的指针中。

        func (a *A) updateB(n int) {
            a.b.c = n
        }
        

        【讨论】:

          【解决方案4】:

          对于要通过函数更新其对象的任何接口,您需要通过引用传递对象。

          package main
          
          import "fmt"
          
          type B struct {
              c int
          }
          
          type A struct {
              b B
          }
          
          func (a *A) updateB(n int) {
              a.b.c = n
          }
          
          func main() {
              a := A{b: B{c: 5}}
          
              fmt.Println(a)
              a.updateB(42)
              fmt.Println(a)
          }
          

          https://play.golang.org/p/_o5sRApo6WP

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-12-04
            • 2011-04-23
            • 1970-01-01
            • 1970-01-01
            • 2020-12-13
            • 2017-02-19
            • 1970-01-01
            相关资源
            最近更新 更多