How to copy two lists in Go

I have this code code in Go:

type T struct{
    l list.List
}
//Global variable
var movsKnight [][]T
var movsKnightQueenWhite []T

//This function create a double slice, and in each position of the slice there is a list
func generateMovsKnight(){

    movsKnight = make([][]T, 64)

    for i := 0; i<64; i++ {

        movsKnight[i] = make([]T,2)

        movsKnight[i][0].l.PushBack(i)

        var col = i/8
        var fil = i%8

        if(col-2 >= 0){
            if(fil-1 >= 0){ movsKnight[i][1].l.PushBack(((col-2)*8)+(fil-1)) }
            if(fil+1 < 8){ movsKnight[i][1].l.PushBack(((col-2)*8)+(fil+1)) }
        }
        
        if(col-1 >=0){
            if(fil-2 >= 0){ movsKnight[i][1].l.PushBack(((col-1)*8)+(fil-2)) }
            if(fil+2 < 8){ movsKnight[i][1].l.PushBack(((col-1)*8)+(fil+2)) }
        }

        if(col+1 < 8){
            if(fil-2 >= 0){ movsKnight[i][1].l.PushBack(((col+1)*8)+(fil-2)) }
            if(fil+2 < 8){ movsKnight[i][1].l.PushBack(((col+1)*8)+(fil+2)) }
        }

        if(col+2 < 8){
            if(fil-1 >= 0){ movsKnight[i][1].l.PushBack(((col+2)*8)+(fil-1)) }
            if(fil+1 < 8){ movsKnight[i][1].l.PushBack(((col+2)*8)+(fil+1)) }
        }        
    }
}

//This function returns one slice of 5 positions with a list in each position
func getMovsKnight(square int)([]T){
    return movsKnight[square]
}

With these functions, I create a slice[][] with a list in each position of the slice.

For example, in movsKnight[0][4] I have a list with one node. And in getMovsKnight, I get the slice in one position, for example, I get movsKnight[0], so this returns a slice of 5 positions and one list in each position.

Now:

func init(){

    movsKnightQueenWhite = make([]T, 2)

    //Fills movsKnight
    generateMovsKnight()

    movsKnightQueenWhite = getMovsKnight(0)
    movsKnightQueenWhite = cutList(movsKnightQueenWhite)

 }

func cutList(slice []T)([]T){

    //I simplify the func in order to do it more understandable
    for e := slice[0].l.Front(); e != nil; e = next {
         next = e.Next() 
         if(borrado == true){ slice[0].l.Remove(e) }
     }
     return slice
}

My problem is that the function cutList is modifying the variable MovsKnight (I dont want to modify this) and it is also modifying movsKnightQueenWhite (that it is correct)

If I print the memory address of both slices (movsKnight y movsKnightQueenWhite), I see that is the same address. So, the function getMovsKnight doesnt do a copy of movsKnight and returns it. I think that cutList is returning the reference of movsKnight and, for this reason, the other methods are modifying movsKnight and they arent modifying movsKnightQueenWhite as I would like.

I would like to know how I can do to copy movsKnight and how avoid to modify the original.

There is a global function named “copy()” that copies slices.

https://golang.org/ref/spec#Appending_and_copying_slices

Thanks for your answer.

I also try to this, but I have the same problem. Go copy the reference of the first in the other slice, so when I do some changes in the second slice, it also changes the first slice. I would like to copy only the value to do changes only in the second slice

Where and how did you add the copy() call? Maybe you have copied too early or too late or not enough.
Please share the current version of cutList so that we are on the same line.

You’re using the list.List, which is a double linked list. You’re copying the list reference, but the links in the list remains. You would have to copy that list as well in order to be able to modify the copy without touching the original.

You should probably not use the linked list either. A slice or similar is usually superior.

2 Likes

I try to copy when I get movs

func getMovsKnight(square int)([]T){
        var aux T[]
        // I want to copy the value to modify without problems
         copy(aux, movsKnight[square])
         return aux
}

Looks like you run into the problem that Jacob explained. copy() is only a shallow copy - it does not follow pointers to copy nested data. So if you copy data containing pointers, you get a copy of the pointers that still point to the same locations.

You would need to write a custom copy function that goes through each slice element and copies the whole list as well. (And as Jacob already recommended, verify if you really need list.List or if a slice would do.)

Ok, I see the problem.

Many thanks for all your help.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.