Путаница с ломтиками Голанга - PullRequest
0 голосов
/ 28 декабря 2018
package main

import (
    "fmt"
)

func main() {
    values := make([]int, 0, 100)
    val := make([][]int, 2)
    for i:=0; i<2; i++ {
        values = values[:0]
        for j:=0; j<2; j++ {
            values = append(values, i+j)
        }
        val[i] = values
        fmt.Println(values, val) //
    }
    fmt.Println(val)
}

https://play.golang.org/p/5x60VfDXbFw

, когда добавление среза , val, как ожидается, будет [[0, 1], [1, 2]], но получено [[1,2],[1,2]]

Ответы [ 3 ]

0 голосов
/ 28 декабря 2018

Вы должны инициализировать значения в цикле for, values = []int{}

код, подобный следующему:

package main

import (
    "fmt"
)

func main() {
    var (
        valLength = 2
    )
    val := make([][]int, valLength)
    for i := 0; i < valLength; i++ {
        values := []int{}
        for j := 0; j < 2; j++ {
            values = append(values, i+j)
        }
        val[i] = values
        fmt.Println(values, val) //
    }
    fmt.Println(val)
}

И вы можете изменить только переменную valLength, чтобы получить любую длину среза, которую вы хотите.

0 голосов
/ 28 декабря 2018

функция среза в go:

Срезы содержат ссылки на базовый массив, и если вы назначаете один срез другому, оба ссылаются на один и тот же массив.

Значение среза будет в последний раз, когда вы измените его.Таким образом, вот два подхода к достижению цели:

использовать copy

func main() {
    values := make([]int, 0, 100)
    val := make([][]int, 2)
    for i := 0; i < 2; i++ {
        values = values[:0]
        for j := 0; j < 2; j++ {
            values = append(values, i+j)
        }
        val[i] = make([]int, 2)
        copy(val[i], values)
        fmt.Println(values, val) //
    }
    fmt.Println(val)
}

срез новых значений в первом цикле for каждый раз

val := make([][]int, 2)
for i := 0; i < 2; i++ {
    values := make([]int, 0, 2)
    for j := 0; j < 2; j++ {
        values = append(values, i+j)
    }
    val[i] = values
    fmt.Println(values, val) //
}
0 голосов
/ 28 декабря 2018

Это происходит потому, что срез val содержит указатели на свои сублим, а не сами субликсы.В своем коде вы изначально размещаете указатель на values в позициях val[0].Затем вы изменяете values и затем устанавливаете указатель на values в val[1].Но и val[0], и val[1] указывают на один и тот же базовый объект (values), который был изменен.

Это можно исправить, создав новый срез values на каждой итерации внешнегоцикл, таким образом, каждый вложенный срез val будет различным срезом.

Например:

func main() {
    val := make([][]int, 2)
    for i:=0; i<2; i++ {
        values := make([]int, 0, 100)
        for j:=0; j<2; j++ {
            values = append(values, i+j)
        }
        val[i] = values
        fmt.Println(values, val) //
    }
    fmt.Println(val)
}

Вывод из fmt.Println:

[0 1] [[0 1] []]    // values, val
[1 2] [[0 1] [1 2]] // values, val
[[0 1] [1 2]]       // val
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...