Golang:使用切片策略切片的多维数组导致奇怪的输出

时间:2016-07-27 07:58:54

标签: multidimensional-array go append

我在golang中使用以下2d数组的简单代码,其中 APPEND 函数导致重复值而不是追加。

package main

import "fmt"

func main() {
    var n int
    fmt.Scanf("%d", &n)
    array := [][]int{}
    row := make([]int, n)
    for _, _ = range row {
        for j, _ := range row {
            fmt.Scanf("%d", &row[j])
        }
        fmt.Println("Printing current Row", row)
        array = append(array, row)
        fmt.Println("Printing curent Array", array)
    }
    fmt.Println("Final Array", array)
}

但奇怪的是,这并不会出乎意料。 如果我想要发生这件事(输入)

2
1 2
3 4

我运行这个程序我得到了这个回报

2     //Dimension for matrix
1     //Iteration one begins
2
Printing current Row [1 2]
Printing curent Array [[1 2]]
3     //Iteration two begins
4
Printing current Row [3 4]
Printing curent Array [[3 4] [3 4]]
Final Array [[3 4] [3 4]]

我没理由说 APPEND 功能导致重复输入的原因。 在那里想要知道如何纠正这个 CONCEPT

2 个答案:

答案 0 :(得分:3)

出现这种情况是因为您没有向row添加新的array切片。每次迭代只会读取覆盖先前值的相同row切片。请尝试以下:

func main() {
    var n int
    fmt.Scanf("%d", &n)
    array := [][]int{}

    for i := 0; i < n; i++ {
        row := make([]int, n) // create a new slice to add next row values
        for j, _ := range row {
            fmt.Scanf("%d", &row[j])
        }
        fmt.Println("Printing current Row", row)
        array = append(array, row)
        fmt.Println("Printing curent Array", array)
    }
    fmt.Println("Final Array", array)
}

答案 1 :(得分:1)

为第一个循环的每次迭代使用新切片,并检查错误

您将新数据读取到旧的相同切片,这就是您拥有重复数据的原因。

如果您想先使用append创建零长度和上限n的数组:
 array := make([][]int, 0, n)
然后将您的第一个循环更改为:for i := 0; i < n; i++ {
并在此循环内部创建新切片:row := make([]int, n)

2路:
使用append(没有fmt.Scan错误检查):

package main

import "fmt"

func main() {
    n := 0
    fmt.Scan(&n)
    slice := make([][]int, 0, n)
    for i := 0; i < n; i++ {
        row := make([]int, n)
        for j, _ := range row {
            fmt.Scan(&row[j])
        }
        slice = append(slice, row)
    }
    fmt.Println(slice)
}

不使用追加读取s[i][j](错误检查):

package main

import "fmt"

func main() {
    var n int
    if m, err := fmt.Scan(&n); m != 1 {
        panic(err)
    }
    s := make([][]int, n)
    for i := 0; i < n; i++ {
        s[i] = make([]int, n)
        for j := 0; j < n; j++ {
            if m, err := fmt.Scan(&s[i][j]); m != 1 {
                panic(err)
            }
        }
    }
    fmt.Println(s)
}

输入:

2
1 2
3 4

输出:

[[1 2] [3 4]]

我认为这个测试样本代码足够清晰 显示切片的切片如何工作(带注释输出):

package main

import "fmt"

func main() {
    s1 := [][]int{}
    s2 := []int{1, 2}
    s1 = append(s1, s2)
    fmt.Println(s1) // [[1 2]]

    s2[0], s2[1] = 3, 4
    fmt.Println(s1) // [[3 4]]

    s1 = append(s1, s2)

    fmt.Println(s1) // [[3 4] [3 4]]

    s2[0], s2[1] = 30, 40
    fmt.Println(s1) // [[30 40] [30 40]]

    fmt.Println(len(s2), cap(s2)) // 2 2

    s3 := [][]int{
        []int{1, 2},
        []int{3, 4},
        s2,
        s2,
    }
    fmt.Println(s3) // [[1 2] [3 4] [30 40] [30 40]]
    s2[0] = 100
    fmt.Println(s3) // [[1 2] [3 4] [100 40] [100 40]]
}

您创建了切片s1,如下所示:
array [0] = row [0],row [1]
array [1] = row [0],row [1]

所以当你改变行时它会看到两次。