Добавить фрагмент структуры в другой - PullRequest
0 голосов
/ 09 ноября 2018

Я новичок в Golang и пытаюсь добавить содержимое фрагмента struct в другой экземпляр. Данные добавляются, но они не видны вне метода. Ниже приведен код.

package somepkg

import (
    "fmt"
)

type SomeStruct struct {
    Name  string
    Value float64
}

type SomeStructs struct {
    StructInsts []SomeStruct
}

func (ss SomeStructs) AddAllStructs(otherstructs SomeStructs) {

    if ss.StructInsts == nil {
        ss.StructInsts = make([]SomeStruct, 0)
    }

    for _, structInst := range otherstructs.StructInsts {
        ss.StructInsts = append(ss.StructInsts, structInst)
    }

    fmt.Println("After append in method::: ", ss.StructInsts)
}

Затем в основном пакете я инициализирую структуры и вызываю метод AddAllStructs.

package main

import (
  "hello_world/somepkg"
  "fmt"
)

func main() {
    var someStructs = somepkg.SomeStructs{
      []somepkg.SomeStruct{
        {Name: "a", Value: 1.0},
        {Name: "b", Value: 2.0},
      },
    }

    var otherStructs = somepkg.SomeStructs{
      []somepkg.SomeStruct{
        {Name: "c", Value: 3.0},
        {Name: "d", Value: 4.0},
      },
    }

    fmt.Println("original::: ", someStructs)
    fmt.Println("another::: ", otherStructs)

    someStructs.AddAllStructs(otherStructs)

    fmt.Println("After append in main::: ", someStructs)
}

Приведенный выше вывод программы:

original:::  {[{a 1} {b 2}]}
another:::  {[{c 3} {d 4}]}
After append in method:::  [{a 1} {b 2} {c 3} {d 4}]
After append in main:::  {[{a 1} {b 2}]}

Я пытаюсь понять, чего мне здесь не хватает, поскольку данные видны в методе. Ценю любую помощь по этому вопросу.

- Anoop

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018

Использовать указатель приемника:

func (ss *SomeStructs) AddAllStructs(otherstructs SomeStructs) {

    if ss.StructInsts == nil {
        ss.StructInsts = make([]SomeStruct, 0)
    }

    for _, structInst := range otherstructs.StructInsts {
        ss.StructInsts = append(ss.StructInsts, structInst)
    }

    fmt.Println("After append in method::: ", ss.StructInsts)
}

Если метод должен мутировать приемник, приемник должен указатель

0 голосов
/ 09 ноября 2018

Вы можете легко решить эту проблему, используя указатель-получатель вместо получателя значения.

func (ss *SomeStructs) AddAllStructs(otherstructs SomeStructs) {

    if ss.StructInsts == nil {
        ss.StructInsts = make([]SomeStruct, 0)
    }

    for _, structInst := range otherstructs.StructInsts {
        ss.StructInsts = append(ss.StructInsts, structInst)
    }

    fmt.Println("After append in method::: ", ss.StructInsts)
} 

Помните, что в go, если вы видите внутреннее срез, это структура, содержащая указатель на структуру данных.

Таким образом, срез в основном не знает емкости вновь добавленного среза, и тот же срез был напечатан.

Во-вторых, вам не нужно возвращать результат добавленного фрагмента. здесь для спасения приходит указатель-получатель, так как получатели значения не могут изменить исходное значение.

код бега на игровой площадке: https://play.golang.org/p/_vxx7Tp4dfN

0 голосов
/ 09 ноября 2018

Вы должны вернуть результат append:

package main

import (
    "fmt"
)

func main() {
    // Wrong
    var x []int
    _ = append(x, 1)
    _ = append(x, 2)

    fmt.Println(x) // Prints []

    // Write
    var y []int
    y = append(y, 1)
    y = append(y, 2)

    fmt.Println(y) // Prints [1 2]
}
...