12.3. 프로그램언어 고(Go)에서의 슬라이스 복사와 덧붙이기

프로그램언어 고(Go)에서의 슬라이스 복사하는 방법

프로그램언어 고(Go)에서 슬라이스를 복사하는 방법은 크게 값 복사와 참조 복사 2가지가 있습니다.

값 복사는 슬라이스를 다른 변수에 할당함으로써 구현할 수 있습니다. 이 때 원본 슬라이스와 복사된 슬라이스는 서로 독립적입니다.


package main

import "fmt"

func main() {
    slice1 := []int{1, 2, 3} // 슬라이스 1 생성

    slice2 := slice1 // slice1을 slice2에 값 복사

    slice2[1] = 20 // slice2만 변경

    fmt.Println(slice1) // [1 2 3] - 변경되지 않음 
    fmt.Println(slice2) // [1 20 3] - 변경됨
}  

위의 예제코드에서 보면 slice1을 slice2에 할당하여 값 복사를 했습니다. 이후 slice2만 변경했지만 slice1은 영향을 받지 않았습니다.

참조 복사는 내장 함수 copy를 사용하는 방법이 있습니다. 이 함수를 사용하면 원본 슬라이스를 변경하지 않고 새로운 슬라이스를 생성할 수 있습니다.


package main

import "fmt"

func main() {
    slice1 := []int{1, 2, 3}

    slice2 := make([]int, len(slice1)) 
    copy(slice2, slice1) // slice1을 slice2에 참조 복사

    slice2[1] = 20  

    fmt.Println(slice1) // [1 2 3] - 변경되지 않음
    fmt.Println(slice2) // [1 20 3] - 변경됨
}

위의 예제코드에서 slice1을 참조하여 slice2를 생성 후 변경했습니다. 하지만 여전히 slice1은 영향을 받지 않았습니다.

이처럼 고(Go)에서 슬라이스를 복사하는 방법은 크게 값 복사와 참조 복사 2가지가 있습니다.
값 복사는 더 많이 사용되고, 참조 복사는 원본 데이터를 보존하고 싶을 때 유용합니다.
예제코드에 있는 2가지 방법을 잘 이해하고 상황에 맞게 사용할 수 있어야 합니다.

프로그램언어 고(Go)에서의 슬라이스 붙이기 방법

프로그램언어 고(Go)에서 슬라이스를 붙이는 방법은 주로 append 함수를 사용합니다.

append 함수는 기존 슬라이스에 다른 슬라이스나 값을 붙여서 새로운 슬라이스를 반환합니다.


package main

import "fmt"

func main() {

    slice1 := []int{1, 2, 3}
    slice2 := []int{4, 5, 6}

    // slice1과 slice2를 붙임
    newSlice := append(slice1, slice2...) 

    fmt.Println(newSlice) // [1 2 3 4 5 6]
}

위의 예제에서 볼 수 있듯이 append 함수의 첫 번째 파라미터는 기존 슬라이스입니다.

두 번째 파라미터부터는 붙이려고 하는 값이나 슬라이스를 지정합니다.

슬라이스를 붙일 때에는 … 문法을 사용하여 펼쳐줍니다.

append 함수를 호출하면 기존 슬라이스를 복사하고 거기에 새로운 값들을 붙인 후에 새로운 슬라이스를 반환합니다.

따라서 기존 슬라이스는 값이 변경되지 않습니다.


slice1 := []int{1, 2, 3}
newSlice := append(slice1, 4, 5, 6)

fmt.Println(slice1) // [1 2 3] (변화 없음) 
fmt.Println(newSlice) // [1 2 3 4 5 6]

위의 예제에서 slice1은 append 호출 후에도 값이 변하지 않았습니다.

append 함수에서 반환된 newSlice에만 추가된 원소들이 들어있습니다.

이러한 특성 때문에 append 함수의 결과를 변수에 저장하고 사용하는 것이 일반적입니다.

프로그램언어 고(Go)에서의 슬라이스 복사 후 변경하기

프로그램언어 고(Go)에서 슬라이스를 복사하고 복사된 슬라이스를 변경하면 원본 슬라이스도 영향을 받을 수 있습니다.

이는 고(Go)의 슬라이스가 실제 배열 데이터를 참조하기 때문입니다. 슬라이스를 대입하면 실제 배열을 공유하게 됩니다.

예를 들어 다음과 같은 코드에서


package main

import "fmt"

func main() {

    slice1 := []int{1, 2, 3} // 슬라이스1 정의

    slice2 := slice1 // 슬라이스1을 slice2에 복사

    slice2[1] = 20 // slice2의 1번 인덱스 값을 변경

    fmt.Println(slice1)
    fmt.Println(slice2) 
}

slice1을 복사한 slice2의 일부 값을 변경했지만, slice1도 변경된 것을 볼 수 있습니다. 왜냐하면 둘 다 같은 배열을 참조하고 있기 때문입니다.

이를 방지하려면 복사된 슬라이스를 위한 새로운 배열을 명시적으로 만들어 주어야 합니다.


package main

import "fmt"

func main() {

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

    slice2 := make([]int, len(slice1))
    copy(slice2, slice1) 

    slice2[1] = 20

    fmt.Println(slice1) 
    fmt.Println(slice2)
}  

위 코드에서 slice2를 위한 새 배열을 make() 함수로 생성했습니다. 그리고 copy() 함수로 slice1의 값들을 slice2로 복사했습니다.

이제 slice2의 값을 변경해도 slice1에는 영향을 주지 않습니다.

슬라이스를 복사할 때는 이와 같이 주의가 필요합니다. 실제 배열을 공유하는 것인지, 별도의 배열을 사용하는 것인지 확인이 중요합니다.

프로그램언어 고(Go)에서의 슬라이스 복사 후 덧붙이기

프로그램언어 고(Go)에서 슬라이스를 복사한 후에 덧붙이기를 하는 방법에 대해 설명드리겠습니다.

슬라이스는 Go 언어의 중요한 자료구조 중 하나입니다. 슬라이스를 복사하고 싶은 경우에는 다음과 같은 방법을 사용할 수 있습니다.


package main

import "fmt"

func main() {

    // 원본 슬라이스
    origSlice := []int{1, 2, 3} 

    // 슬라이스 복사
    copySlice := make([]int, len(origSlice))
    copy(copySlice, origSlice)

    fmt.Println(origSlice) // [1 2 3]
    fmt.Println(copySlice) // [1 2 3]

} 

위의 코드에서 copy 함수를 사용하여 origSlice 슬라이스를 copySlice로 복사합니다.

이렇게 복사한 슬라이스에 추가적인 원소를 덧붙이고 싶다면 append 함수를 사용할 수 있습니다.


package main

import "fmt"

func main() {

    // 원본 슬라이스 
    origSlice := []int{1, 2, 3}

    // 슬라이스 복사
    copySlice := make([]int, len(origSlice)) 
    copy(copySlice, origSlice)

    // 슬라이스에 원소 덧붙이기
    copySlice = append(copySlice, 4, 5)

    fmt.Println(origSlice) // [1 2 3]
    fmt.Println(copySlice) // [1 2 3 4 5]

}

위의 코드에서 복사한 copySlice에 append 함수를 사용하여 4와 5를 덧붙였습니다. 기존 원소들을 유지한 채로 추가적인 원소를 덧붙일 수 있습니다.

append 함수 사용 시 주의할 점은 원본 슬라이스가 가리키는 배열의 용량을 초과하는 경우, Go 언어 내부적으로 새로운 배열을 할당하고 데이터를 복사합니다.

이때 원본 슬라이스의 값은 변하지 않지만, 복사된 슬라이스가 가리키는 배열의 주소는 변경될 수 있습니다.

따라서 append 함수 사용 후에는 반드시 변수에 할당 해주는 것이 안전합니다.

프로그램언어 고(Go)에서의 슬라이스 붙이고 복사하기

프로그램언어 고(Go)에서 슬라이스를 붙이거나 복사하기 위해서는 append와 copy 내장 함수를 사용할 수 있습니다.

package main

import "fmt"

func main() {
    s1 := []int{1, 2, 3}
    s2 := []int{4, 5, 6}

    // 슬라이스 붙이기 - append
    s1 = append(s1, s2...)
    fmt.Println(s1)

    // 슬라이스 복사하기 - copy
    s3 := make([]int, len(s1))
    copy(s3, s1)
    fmt.Println(s3)
}

append 함수는 첫 번째 파라미터 슬라이스에 두 번째 파라미터 슬라이스를 붙입니다.

copy 함수는 첫 번째 파라미터 슬라이스에 두 번째 파라미터 슬라이스를 복사합니다. 복사할 공간을 첫 번째 파라미터로 사전에 할당해야 합니다.

슬라이스를 붙이고 싶은 경우 append를 사용하고, 값 복사를 원하는 경우 copy를 사용합니다.

append 함수에서 … 문법은 두번째 파라미터 슬라이스를 풀어헤쳐서 붙입니다.

만약 … 문법 없이 단순히 append(s1, s2) 처럼 호출하면, s2 슬라이스 자체가 s1의 요소로 추가되므로 주의가 필요합니다.

Leave a Comment