Почему адрес элемента в срезе одинаков? а как их скопировать в указатель?

У меня есть кусок кода:

    //initialize a slice
    arr := make([]int, 0)
    arr = append(arr, 1, 2)
    for _, k := range arr {
        fmt.Printf("%p  %+v\n", &k, k)
    }

    //make a copy, but the element is a pointer
    arrP := make([]*int, 0)
    for _, k := range arr {
        arrP = append(arrP, &k)
    }
    //why arrP is different with arr?
    for _, k := range arrP {
        fmt.Printf("%p  %+v\n", k, *k)
    }

результаты: 0xc000018088 1 0xc000018088 2 0xc000090000 2 0xc000090000 2 мои вопросы:
почему адрес тот же?
почему значение arrP[0] не равно 1?


go
person chaos    schedule 24.02.2020    source источник
comment
Выражение &k — это адрес переменной k, а не элемента среза. Используйте &arr[i], чтобы получить адрес элемента среза.   -  person Cerise Limón    schedule 24.02.2020
comment
Возможный дубликат 1, 2, 3, 4, ...   -  person Cerise Limón    schedule 24.02.2020


Ответы (1)


См. раздел Go CommonMistakes: Использование ссылки на переменную итератора цикла

почему адрес тот же?

Значение k обновляется по мере продвижения цикла вперед.

почему значение arrP[0] не равно 1?

То же, что и выше.

Чтобы продемонстрировать модифицированную версию примера, который вы предоставили:

    arr := make([]int, 0)
    arr = append(arr, 1, 2)
    for i, _ := range arr {
        fmt.Printf("%p  %+v\n", &arr[i], arr[i])
    }

    arrP := make([]*int, 0)
    for i, _ := range arr {
        arrP = append(arrP, &arr[i])
    }

    for i, _ := range arrP {
        fmt.Printf("%p  %+v\n", arrP[i], *arrP[i])
    }

Результаты:

0xc00009a010  1
0xc00009a018  2
0xc00009a010  1
0xc00009a018  2
person Shangjian Ding    schedule 24.02.2020
comment
Код в вашем ответе возвращает те же результаты, что и OP. Вы уверены, что не опубликовали тот же оригинальный фрагмент кода? - person zerkms; 24.02.2020