переход — Изменение указателя на фрагмент не изменяет оригинал

#pointers #go

# #указатели #Вперед

Вопрос:

Я пытаюсь создать структуру, в которой одно поле является указателем на существующий пустой фрагмент. Затем я изменяю поле struct , а позже пытаюсь получить новое содержимое из исходного фрагмента — но он по-прежнему пуст!

Вот демонстрационный код:

 package main

import (
    "fmt"
)

type A struct {
    B []int
}

func main() {
    c := []int{}

    a := amp;A{
        B: c,
    }

    a.B = append(a.B, 5)

    fmt.Println(c)
    fmt.Println(a)
}
 

В результате здесь получается:

 []
amp;{[5]}
 

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

Комментарии:

1. B []int это не указатель на срез, это срез. Вы хотите B *[]int . Совершите экскурсию по Го еще раз.

2. Позже я переписываю его с c помощью, и фрагменты передаются по ссылке, не так ли ?!

3. Ничто в Go не передается по ссылке. Фрагменты содержат указатель на базовый массив.

4. @Adrian, хорошо, ты можешь исправить мой демонстрационный код, чтобы он работал как ожидалось?

5. Прочитайте комментарий Фолькера, это изменение, которое нужно внести в этот код. Я бы сказал, что это довольно необычно (сохранение указателя на поле структуры, подобное этому) в качестве варианта использования, и ваш существующий код будет в порядке в большинстве случаев (просто ссылка на поле в указателе на структуру), так что, возможно, это проблема XY.

Ответ №1:

Вы можете использовать фрагмент указателей, как в примере ниже:

 package main

import (
    "fmt"
)

type A struct {
    B *[]int
}

func main() {
    c := []int{}

    a := amp;A{
        B: amp;c,
    }

    *a.B = append(*a.B, 4)
    *a.B = append(*a.B, 5)

    fmt.Println(c)

    fmt.Println(a.B)
}
 

Результат
Результат