Go 프로그래밍 - 슬라이스

슬라이스

크기 정보를 가지고 있는 배열 포인터이다.

1. 초기화 방법

  1. 크기가 정의되어있지 않은 배열로 선언하는 방법
# 길이가 0인 배열로 선언
var slice []int
  1. {}를 이용한 초기화 방법
# [1 2 3]
var slice1 = []int{1,2,3}

# 5번 인덱스에 2 / 10번 인덱스에 3을 할당
# [1 0 0 0 0 2 0 0 0 0 3]
var slice2 = []int{1, 5:2, 10:3}
# 주의: 아래의 두 구분은 다릅니다.
var array = [...]int{1,2,3} 	# 배열 선언
var slice = []int{1,2,3}	# 슬라이스 선언
  1. make()를 이용한 초기화
var slice = make([]int, 3)

2. 슬라이스 요소 접근

# 특정 인덱스에 접근
var slice = make([]int, 3)
slice[1] = 5

# 순회1 (for문)
var slice = []int{1,2,3}
for i:=0; i < len(slice); i++ {
	fmt.Println(slice[i])	
}

# 순회2 (range문)
var i, v := range slice {
	slice[i] = v * 2
}

3. 요소 추가

append()를 이용

var slice = []int{1,2,3}

# 한개 요소 추가
slice2 = append(slice, 4)
# [1 2 3 4]

# 여러개 추가
slice3 = append(slice, 3, 4, 5, 6)
# [1 2 3 3 4 5 6]

# 기존의 슬라이스를 이용해서 여러개 추가
slice4 = append(slice3, slice2...)
# [1 2 3 3 4 5 6 1 2 3 4]

4. 슬라이싱

배열의 일부를 집어내는 기능

# 단 endIdx 위치의 요소는 제외. startIdx ~ (endIdx-1) 까지의 범위
array[startIdx:endIdx]

슬라이싱으로 배열 일부를 가리키는 슬라이스 만들기

array := [5]int{1,2,3,4,5}
slice := array[1:3]

그렇다면 len과 cap은 어떻게 될까?

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

fmt.Printf("slice1 len:%d, cap:%d\n", len(slice1), cap(slice1))
// >> slice1 len:2, cap:4

fmt.Printf("slice2 len:%d, cap:%d\n", len(slice2), cap(slice2))
// >> slice2 len:1, cap:3
  • len = endIdx - startIdx
  • cap = 가리키는 배열의 cap - startIdx

5. 슬라이스 복제

두 슬라이스가 서로 같은 배열을 가리켜서 발생하는 문제를 방지

  • 가장 기본적인 방법
slice1 := []int{1,2,3,4,5}
slice2 := make([]int, len(slice1))

// slice 복제
for idx, value := range slice1 {
  slice2[idx] = value
}

slice1[0] = 500

fmt.Println(slice1)
fmt.Println(slice2)
  • append를 이용한 방법
slice1 := []int{1,2,3,4,5}
# 요소를 펼쳐서 하나씩 추가
slice2 := append([]int{}, slice1...)

slice1[0] = 500

fmt.Println(slice1)
fmt.Println(slice2)
  • copy를 이용한 방법
  • len 만큼만 복사된다
slice := []int{1,2,3,4,5}
slice1 := make([]int, 3, 10)
slice2 := make([]int, 10, 10)

copy_cnt1 := copy(slice1, slice)
copy_cnt2 := copy(slice2, slice)

fmt.Println(copy_cnt1, slice1)
// >> 3 [1 2 3]

fmt.Println(copy_cnt2, slice2)
// >> 5 [1 2 3 4 5 0 0 0 0 0]

5. 요소 삭제

  • 일반적인 방법
slice := []int{1,2,3,4,5}
remove_idx := 3

for i:=remove_idx+1;i<len(slice);i++ {
  slice[i-1] = slice[i]
}

slice = slice[:len(slice)-1]
fmt.Println(slice)
// >> [1 2 3 5]
  • append() 함수로 코드 개선하기
slice := []int{1,2,3,4,5}
remove_idx := 3

slice = append(slice[:remove_idx], slice[remove_idx+1])

fmt.Println(slice)
// >> [1 2 3 5]

6. 요소 추가

  • 일반적인 방법
  • 맨 뒤에 요소 하나 추가해서 하나씩 밀어낸뒤 해당 위치에 값을 넣는다
slice := []int{1,2,3,4,5}
slice1 := append(slice, 0)
idx_to_append := 2
value_to_append := 500

for i:=len(slice) ; i > idx_to_append ; i-- {
  slice1[i] = slice1[i-1]
}
slice1[idx_to_append] = value_to_append

fmt.Println(slice1)
  • append() 함수로 코드 개선하기
slice := []int{1,2,3,4,5}
idx_to_append := 2
value_to_append := 500

slice = append(slice[:idx_to_append], append([]int{value_to_append}, slice[idx_to_append:]...)...)

fmt.Println(slice)
  • 불필요한 메모리 사용이 없도록 코드 개선
    • append()를 사용하는 경우 append([]int{value_to_append}, slice[idx_to_append:]...)로 인해 임시 슬라이스가 생성되어 불필요한 메모리를 차지한다
slice := []int{1,2,3,4,5}
slice = append(slice, 0)

idx_to_append := 2
value_to_append := 500

copy(slice[idx_to_append+1:], slice[idx_to_append:])

slice[idx_to_append] = value_to_append

fmt.Println(slice)

7. 정렬하기

  • sort 패키지를 사용
  • Len, Less, Swap 메서드만 있으면 어떤 구조체든 정렬 가능
slice := []int{6,1,4,7,5,2}
sort.Ints(slice)
fmt.Println(slice)
// >> [1 2 4 5 6 7]

좋은 웹페이지 즐겨찾기