Golang slice reference confusion

Multi tool use
Multi tool use












-2














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



when appending slice,val is expected to be [[0, 1], [1, 2]], but got [[1,2], [1,2]]










share|improve this question






















  • That's not the result I saw on go play.
    – Ibu
    Dec 28 '18 at 3:28
















-2














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



when appending slice,val is expected to be [[0, 1], [1, 2]], but got [[1,2], [1,2]]










share|improve this question






















  • That's not the result I saw on go play.
    – Ibu
    Dec 28 '18 at 3:28














-2












-2








-2







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



when appending slice,val is expected to be [[0, 1], [1, 2]], but got [[1,2], [1,2]]










share|improve this question













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



when appending slice,val is expected to be [[0, 1], [1, 2]], but got [[1,2], [1,2]]







go






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Dec 28 '18 at 3:24









preyta

75




75












  • That's not the result I saw on go play.
    – Ibu
    Dec 28 '18 at 3:28


















  • That's not the result I saw on go play.
    – Ibu
    Dec 28 '18 at 3:28
















That's not the result I saw on go play.
– Ibu
Dec 28 '18 at 3:28




That's not the result I saw on go play.
– Ibu
Dec 28 '18 at 3:28












3 Answers
3






active

oldest

votes


















1














This happens because the slice val contains pointers to its subslices, rather than the subslices themselves. In your code, you initially place a pointer to values in positions val[0]. Then you modify values and then set a pointer to values in val[1]. But both val[0] and val[1] point to the same underlying object (values), which has been modified.



You can fix this by creating a new values slice on each iteration of the outer loop, this way each sub slice of val will be a different slice.



For example:



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)
}


Output from fmt.Println:



[0 1] [[0 1] ]    // values, val
[1 2] [[0 1] [1 2]] // values, val
[[0 1] [1 2]] // val





share|improve this answer





























    1














    slice feature in go:




    Slices hold references to an underlying array, and if you assign one
    slice to another, both refer to the same array.




    The value of slice will be the last time you modify it. Thus, here's two approach to achieve the goal.



    use 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)
    }


    new values slice in first for-loop each time



    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) //
    }





    share|improve this answer





























      0














      You should initialize values in your for loop, values = int{}



      code like this:



      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)
      }


      And you only change variable valLength to get any length of slice you want.






      share|improve this answer





















        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53953333%2fgolang-slice-reference-confusion%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        3 Answers
        3






        active

        oldest

        votes








        3 Answers
        3






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        1














        This happens because the slice val contains pointers to its subslices, rather than the subslices themselves. In your code, you initially place a pointer to values in positions val[0]. Then you modify values and then set a pointer to values in val[1]. But both val[0] and val[1] point to the same underlying object (values), which has been modified.



        You can fix this by creating a new values slice on each iteration of the outer loop, this way each sub slice of val will be a different slice.



        For example:



        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)
        }


        Output from fmt.Println:



        [0 1] [[0 1] ]    // values, val
        [1 2] [[0 1] [1 2]] // values, val
        [[0 1] [1 2]] // val





        share|improve this answer


























          1














          This happens because the slice val contains pointers to its subslices, rather than the subslices themselves. In your code, you initially place a pointer to values in positions val[0]. Then you modify values and then set a pointer to values in val[1]. But both val[0] and val[1] point to the same underlying object (values), which has been modified.



          You can fix this by creating a new values slice on each iteration of the outer loop, this way each sub slice of val will be a different slice.



          For example:



          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)
          }


          Output from fmt.Println:



          [0 1] [[0 1] ]    // values, val
          [1 2] [[0 1] [1 2]] // values, val
          [[0 1] [1 2]] // val





          share|improve this answer
























            1












            1








            1






            This happens because the slice val contains pointers to its subslices, rather than the subslices themselves. In your code, you initially place a pointer to values in positions val[0]. Then you modify values and then set a pointer to values in val[1]. But both val[0] and val[1] point to the same underlying object (values), which has been modified.



            You can fix this by creating a new values slice on each iteration of the outer loop, this way each sub slice of val will be a different slice.



            For example:



            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)
            }


            Output from fmt.Println:



            [0 1] [[0 1] ]    // values, val
            [1 2] [[0 1] [1 2]] // values, val
            [[0 1] [1 2]] // val





            share|improve this answer












            This happens because the slice val contains pointers to its subslices, rather than the subslices themselves. In your code, you initially place a pointer to values in positions val[0]. Then you modify values and then set a pointer to values in val[1]. But both val[0] and val[1] point to the same underlying object (values), which has been modified.



            You can fix this by creating a new values slice on each iteration of the outer loop, this way each sub slice of val will be a different slice.



            For example:



            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)
            }


            Output from fmt.Println:



            [0 1] [[0 1] ]    // values, val
            [1 2] [[0 1] [1 2]] // values, val
            [[0 1] [1 2]] // val






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Dec 28 '18 at 3:39









            Henry Woody

            3,9562824




            3,9562824

























                1














                slice feature in go:




                Slices hold references to an underlying array, and if you assign one
                slice to another, both refer to the same array.




                The value of slice will be the last time you modify it. Thus, here's two approach to achieve the goal.



                use 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)
                }


                new values slice in first for-loop each time



                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) //
                }





                share|improve this answer


























                  1














                  slice feature in go:




                  Slices hold references to an underlying array, and if you assign one
                  slice to another, both refer to the same array.




                  The value of slice will be the last time you modify it. Thus, here's two approach to achieve the goal.



                  use 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)
                  }


                  new values slice in first for-loop each time



                  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) //
                  }





                  share|improve this answer
























                    1












                    1








                    1






                    slice feature in go:




                    Slices hold references to an underlying array, and if you assign one
                    slice to another, both refer to the same array.




                    The value of slice will be the last time you modify it. Thus, here's two approach to achieve the goal.



                    use 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)
                    }


                    new values slice in first for-loop each time



                    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) //
                    }





                    share|improve this answer












                    slice feature in go:




                    Slices hold references to an underlying array, and if you assign one
                    slice to another, both refer to the same array.




                    The value of slice will be the last time you modify it. Thus, here's two approach to achieve the goal.



                    use 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)
                    }


                    new values slice in first for-loop each time



                    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) //
                    }






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Dec 28 '18 at 4:01









                    Bob Fred

                    1795




                    1795























                        0














                        You should initialize values in your for loop, values = int{}



                        code like this:



                        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)
                        }


                        And you only change variable valLength to get any length of slice you want.






                        share|improve this answer


























                          0














                          You should initialize values in your for loop, values = int{}



                          code like this:



                          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)
                          }


                          And you only change variable valLength to get any length of slice you want.






                          share|improve this answer
























                            0












                            0








                            0






                            You should initialize values in your for loop, values = int{}



                            code like this:



                            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)
                            }


                            And you only change variable valLength to get any length of slice you want.






                            share|improve this answer












                            You should initialize values in your for loop, values = int{}



                            code like this:



                            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)
                            }


                            And you only change variable valLength to get any length of slice you want.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Dec 28 '18 at 3:50









                            yusher

                            1665




                            1665






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.





                                Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                Please pay close attention to the following guidance:


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53953333%2fgolang-slice-reference-confusion%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                yV,K 4 aBdr88,RG8eizAbbwtBlC1B n 6 Q,BzCG 4EUcZWHxW,KZuMix xpIxRgTYaA1PerJ kCrGqttBCP 6ZHPTM9D1TlMSM9W2uaV Vx26sO
                                BOrYuh2CiwD5aaed8x694mBvCbNyJlYRm7e5PvIad5M

                                Popular posts from this blog

                                Monofisismo

                                compose and upload a new article using a custom form

                                “attempting to read past stream EOM” using Sybase.AdoNet4.AseClient