Go ссылка на указатель подлисса - PullRequest
0 голосов
/ 11 января 2020

Результат s равен [1, 2, 3], я думал, что срезы содержат ссылку на базовый массив. Разве это не так?

package main

import (
    "fmt"
)

func main() {
    s := []int{1, 2, 3}
    ss := s[1:]
    ss = append(ss, 4)

    for _, v := range ss {
        v += 10
    }

    for i := range ss {
        ss[i] += 10
    }

    fmt.Println(s)
}

Ответы [ 2 ]

1 голос
/ 11 января 2020

Похоже, вы создали копию среза s и внесли изменения в копию среза ss, полагая, что изменения также будут переданы в срез, из которого была сделана копия.

Первый для l oop также проходит по элементам слайса ss, но фактически ничего с ними не делает, потому что range также создает копию при предоставлении значений элементов, поэтому он не ' на самом деле ничего не делать!

Похоже, вы пытаетесь сделать следующее:

  1. Добавить значение 4 к слайсу s
  2. Возьмите каждое значение из индекса 1 из slice до конца среза и добавьте 10

Если это так, это должно помочь вам выполнить sh, что:

package main

import (
    "fmt"
)

func main() {
    s := []int{1, 2, 3}
    s = append(s, 4)

    for i := range s {
        if i == 0 {
            continue
        }
        s[i] += 10
    }

    fmt.Println(s)
}

Вы можете увидеть это на игровой площадке Go: Ссылка

0 голосов
/ 11 января 2020

Я думал, что срезы содержат ссылку на базовый массив. Разве это не так?

Да, это так. Но вы создали массив длиной 3 с этим оператором:

s := []int{1, 2, 3}

Когда вы добавили элемент к ss, это потребовало выделения нового, более длинного массива. Таким образом, вы потеряли связь между ss и s с этим оператором:

ss = append(ss, 4)

Вы можете убедиться в этом, запустив этот пример:

package main

import (
    "fmt"
)

func main() {
    s := []int{1, 2, 3}
    ss := s[1:]
    ss[0] += 5
    ss = append(ss, 4)
    ss[0] += 100
    fmt.Println(s)
}

Какой выводится [1 7 3].

Если вы измените инициализацию s, чтобы иметь длину, превышающую три, новое выделение массива не потребуется, и связь между s и ss будет сохранена:

package main

import (
    "fmt"
)

func main() {
    s := make([]int, 3, 4)
    s[0], s[1], s[2] = 1, 2, 3
    ss := s[1:]
    ss[0] += 5
    ss = append(ss, 4)
    ss[0] += 100
    fmt.Println(s)
}

Вывод: [1 107 3]


Ответ, который теоретизирует, что проблема является копией диапазона среза, является неправильным, что можно показать в следующем примере:

package main    

import (    
    "fmt"    
)    

func main() {    
    s := make([]int, 3, 4)    
    s[0], s[1], s[2] = 1, 2, 3    
    ss := s[1:]    
    ss = append(ss, 4)    
    for i := range ss {    
        ss[i] += 10    
    }    
    fmt.Println(s)    
}    

Выход: [1 12 13]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...