[1. 배열]
- Go 에서 배열은 Slice 와 달리 고정된 크기의 길이를 갖는다.
- 또한, 같은 자료형을 저장 할 지라도 이 길이가 다르면 서로 다른 자료형으로 처리한다.
- 아래 코드에서 주석을 해제하면 실행과 빌드 모두 되지 않는다.
[2. Slice]
- 배열을 기초로 하지만, 그 크기를 동적으로 관리 할 수 있다.
- 또한, 부분 Slice 가 가능하다.
- 실제로, 배열과 비슷하게 선언을 하지만, 그 길이를 따로 명시하지 않는다.
[3. 예제]
package main
import "fmt"
func slice_test(sl []int) {
if len(sl) > 0 {
sl[0] = 9
}
fmt.Printf("%p ", &sl)
fmt.Println(sl)
}
func array_test(arr [5]int) {
//arr = append(arr, 7)
arr[0] = 7
fmt.Printf("%p ", &arr)
fmt.Println(arr)
}
func array_test1(arr [7]int) {
arr[0] = 9
fmt.Println(arr)
}
func main() {
var sl1 []int
sl2 := []int{}
sl3 := make([]int, 0, 5)
sl4 := make([]int, 5, 20)
slice_test(sl1)
fmt.Printf("%p ", &sl1)
fmt.Println(sl1)
slice_test(sl2)
fmt.Printf("%p ", &sl2)
fmt.Println(sl2)
slice_test(sl3)
fmt.Printf("%p ", &sl3)
fmt.Println(sl3)
slice_test(sl4)
fmt.Printf("%p ", &sl4)
fmt.Println(sl4)
fmt.Println("==========")
var ar1 [5]int
ar2 := [5]int{}
array_test(ar1)
fmt.Printf("%p ", &ar1)
fmt.Println(ar1)
array_test(ar2)
fmt.Printf("%p ", &ar2)
fmt.Println(ar2)
//array_test1(ar2)
}
[4. 출력 및 해석]
배열과 달리 Slice를 Pass by value 형태로 넘겼을 때 출력이 다르다.
특히, 7번 8번 라인에서 Slice의 주소가 다른데 내부 데이터는 같다는 것을 볼 수 있다.
이는 Slice 를 관리하는 구조에 대한 차이이다.
C 관점에서 보면 Slice 의 데이터 구조는 아래와 같다.
- T *ptr
- int length;
- int capacity
즉, Slice를 Pass by value 로 넘겼을 때 내부 자료구조를 그대로 복사하기 때문에,
Slice 내 내부 배열을 참조하게 되는 것이다.
따라서 변경 된 사항이 원래 Slice 에도 반영 된 것이고,
배열은 그 자체가 하나의 자료형이라 볼 수 있으므로,
Pass by value 로 넘겼을 때 원래 데이터를 참조하지 않기 때문에, 내부 값이 변경되지 않은 것이다.
'Go' 카테고리의 다른 글
GO111MODULE (0) | 2022.08.10 |
---|---|
go 패키지 설치, 관리 (0) | 2022.08.10 |
ubuntu go version update (0) | 2022.04.06 |
cgo (0) | 2022.03.19 |
Slice length, capacity and append, copy function (0) | 2022.02.08 |