이 글은 골든래빗 《Tucker의 Go 언어 프로그래밍》의 18장 써머리입니다.
[]
안에 배열의 갯수를 적지 않고 선언한다.var slice []int // 길이가 0인 슬라이스 생성
{}
를 사용해 초기화var slice1 = []int{1, 2, 3} //[1 2 3]
var slice1 = []int{1, 5:2, 10:3} //[1 0 0 0 2 0 0 0 0 3]
make()
를 사용한 초기화var slice = make([]int, 3) //길이가 3인 int 슬라이스를 갖는다. [0 0 0]
func Test_append(t *testing.T) {
arr := []int{1, 2, 3, 4, 5}
arr2 := append(arr, 6)
t.Log(arr, arr2) //[1 2 3 4 5] [1 2 3 4 5 6]
}
func Test_appendMoreThanTwo(t *testing.T) {
arr := []int{1, 2, 3, 4, 5}
arr2 := []int{6, 7, 8, 9, 10}
arrAppend := append(arr, arr2...)
t.Log(arrAppend) //[1 2 3 4 5 6 7 8 9 10]
}
reflect
패키지의 SliceHeader
구조체를 사용해 내부 구현을 살펴볼 수 있다.type SliceHeader struct {
Data uintptr
Len int
Cap int
}
func Test_SliceHeader(t *testing.T) {
arr := []int{1, 2, 3, 4, 5}
header := (*reflect.SliceHeader)(unsafe.Pointer(&arr))
log.Println(header.Data, header.Len, header.Cap)
}
func Test_makeSlice(t *testing.T) {
arr := make([]int, 3)
header := (*reflect.SliceHeader)(unsafe.Pointer(&arr))
log.Println(header.Data, header.Len, header.Cap) //1374393540056 3 3
}
func Test_makeSlice2(t *testing.T) {
arr := make([]int, 3, 5)
header := (*reflect.SliceHeader)(unsafe.Pointer(&arr))
log.Println(header.Data, header.Len, header.Cap) //1374396415432 3 5
}
func Test_betweenSliceAndArray(t *testing.T) {
arr := [5]int{1, 2, 3, 4, 5}
slice := []int{1, 2, 3, 4, 5}
func(arr [5]int) {
arr[2] = 10
}(arr)
func(slice []int) {
slice[2] = 10
}(slice)
log.Println(arr) //[1 2 3 4 5]
log.Println(slice) //[1 2 10 4 5]
}
남은 빈 공간 = cap - len
array[startIdx:endIdx]
startIdx, endIdx 생략 가능
startIdx <= slice < endIdx
func Test_SlicingPointer(t *testing.T) {
arr := []int{1, 2, 3, 4, 5}
slice := arr[1:3]
arr[1] = 10
log.Println(slice) //[10 3]
slice[1] = 100
log.Println(arr) //[1 10 100 4 5]
}
func Test_SlicingCapLen(t *testing.T) {
arr := []int{1, 2, 3, 4, 5}
slice := arr[1:2]
log.Println(len(arr), cap(arr)) //5 5
log.Println(len(slice), cap(slice))//1 4
slice = arr[2:3]
log.Println(len(arr), cap(arr)) //5 5
log.Println(len(slice), cap(slice)) //1 3
}
func Test_SlicingAppend(t *testing.T) {
arr := []int{1, 2, 3, 4, 5}
slice := arr[1:2]
slice = append(slice, 10)
t.Log(arr) //[1 2 10 4 5]
t.Log(slice) //[2 10]
}
func Test_SlicedSliceSlicing(t *testing.T) {
arr := []int{1, 2, 3, 4, 5}
slice := arr[1:3] //[2 3]
slice1 := slice[1:2] //[3]
t.Log(slice1) //[3]
}
처음부터 슬라이싱
slice2 := slice1[0:3]
slice2 := slice1[:3]
끝까지 슬라이싱
slice2 := slice1[3:len(slice1)]
slice2 := slice1[3:]
전체 슬라이싱
slice2 := slice1[0:len(slice1)]
slice2 := slice1[:]
인덱스 3개로 슬라이싱해 cap 크기 조절
func Test_SlicingThreeIndex(t *testing.T) {
arr := []int{1, 2, 3, 4, 5}
slice := arr[1:3:4]
t.Log(slice) //[2 3]
t.Log(len(slice), cap(slice)) //2 3
}
For문 사용
func Test_SliceCopyByFor(t *testing.T) {
arr := []int{1, 2, 3, 4, 5}
slice := make([]int, 5, 5)
for i := 0; i < len(arr); i++ {
slice[i] = arr[i]
}
arr = nil
t.Log(arr) //[]
t.Log(slice) //[1 2 3 4 5]
}
append() 내장함수 사용
func Test_SliceCopyByAppend(t *testing.T) {
arr := []int{1, 2, 3, 4, 5}
var slice []int
slice = append(slice, arr...)
arr = nil
t.Log(arr) //[]
t.Log(slice) //[1 2 3 4 5]
}
copy() 내장함수 사용
func Test_SliceCopy(t *testing.T) {
arr := []int{1, 2, 3, 4, 5}
slice := make([]int, 5, 5)
copy(slice, arr)
arr = nil
t.Log(arr) //[]
t.Log(slice) //[1 2 3 4 5]
}
//[]int{1,2,3,4,5}의 2번 인덱스에 10추가하는 경우
func Test_SliceAddElementByAppend(t *testing.T) {
arr := []int{1, 2, 3, 4, 5}
targetIndex := 2
var slice []int
slice = append(arr[:targetIndex], append([]int{10}, arr[targetIndex:]...)...)
t.Log(slice) //[1 2 10 3 4 5]
}
func Test_SliceAddElementByCopy(t *testing.T) {
arr := []int{1, 2, 3, 4, 5}
targetIndex := 2
slice := make([]int, len(arr)+1, cap(arr)+1)
copy(slice[:targetIndex], arr[:targetIndex])
copy(slice[targetIndex+1:], arr[targetIndex:])
slice[targetIndex] = 10
t.Log(slice) //[1 2 10 3 4 5]
}
func Test_sortSlice(t *testing.T) {
ints := []int{5, 1, 2, 3, 4}
strings := []string{"나", "라", "다", "가"}
sort.Ints(ints)
sort.Strings(strings)
t.Log(ints)
t.Log(strings)
}
//나이 오름차순, 나이 같을경우 이름 내림차순
type User struct {
Name string
Age int
}
type Users []User
func (u Users) Len() int { return len(u) }
func (u Users) Less(i, j int) bool {
if u[i].Age < u[j].Age {
return true
}
return u[i].Name > u[j].Name
}
func (u Users) Swap(i, j int) { u[i], u[j] = u[j], u[i] }
func Test_sortStructBySort(t *testing.T) {
users := []User{
{"Coen", 30},
{"Alice", 20},
{"Bob", 30},
}
sort.Sort(Users(users))
t.Log(users) //[{Alice 20} {Coen 30} {Bob 30}]
}
//나이 오름차순, 나이 같을경우 이름 내림차순
func Test_sortStructBySlice(t *testing.T) {
type User struct {
Name string
Age int
}
users := []User{
{"Coen", 34},
{"Alice", 20},
{"Bob", 30},
}
sort.Slice(users, func(i, j int) bool {
return users[i].Age < users[j].Age
})
t.Log(users) //[{Alice 20} {Coen 30} {Bob 30}]
}