티스토리 뷰

golang

[golang]슬라이스(slice)란?

Xion 2021. 7. 4. 18:51

앞에서 설명한 배열과 슬라이스의 관계에 대해 배열을 알아보았고, 이번에는 슬라이에 대해 알아보겠습니다.

 

| 슬라이스

 

 

특징

- 배열과 비슷하지만 길이가 고정적 X
- 즉, 동적으로 크기가 늘어난다 (가변적)
- 참조 값 타입이다 (레퍼런스 타입)

- 슬라이스는 두 가지로 선언할 수 있습니다.

- slice는 web data를 가져올 때 주로 많이 사용합니다.

 

 

1. slice 선언 방법

 

package main

func main(){

		//case1 배열처럼 선언
	var slice []int
	slice2 := []int{} //가변형
	slice3 := []int{1,2,3,4,5}//길이 :5 용량 :5 
	slice4 := [][]int{
		{1,2,3,4,5}
		,{6,7,8,9,10}
	}

	//slice 수정
	slice3[4] = 10
    
}

 

2. make 선언

 

- make 선언은 (자료형, 길이, 용량)를 명시하여 함께 선언합니다.

 

문법

//case2 make(자료형,길이, 용량 (생략시 길이)포함) 선언
var slice5 []int = make([]int,5,10)

//가장 많이 선호하는 방법
var slice6 = make([]int,5)

//짧은 선언
slice7 :=  make([]int,7,100)

 

그림으로 설명해보자면, 위 그림과 같습니다.

용량 10짜리인 길이가 5인 배열을 make 선언하였습니다.

 

다만,


길이보다 용량이 더 크게 선언 했다고 해서 나머지 용량값들이 0으로 초기화되어 접근할 수 있는 것은 아니란 점

 

꼭 알아두시길 바랍니다.

 

예를들어,

 

길이 5짜리인 슬라이스 배열 변수에 길이 6번째를 접근하려 하면 오류가 납니다. 

잘 알아두세요 !

 

 

| 일반 배열 vs slice(슬라이스)배열 타입 증명

package main

import "fmt"

func main() {
	//일반 배열과 슬라이스 배열 참조 타입 증명

	//일반 배열
	arr1 := [3]int{1, 2, 3}
	var arr2 [3]int

	//복사
	arr2 = arr1
	arr2[0] = 7
	fmt.Println(arr1)
	fmt.Println(arr2)

	fmt.Println()

	//슬라이스 배열
	sliceArr := []int{1, 2, 3} //가변형
	var slice2 []int           //가변형

	slice2 = sliceArr
	slice2[0] = 7
	fmt.Println(sliceArr)
	fmt.Println(slice2)
}

일반 배열 같은 경우 slice처럼 참조에 의한 타입이 아니기 때문에 배열을 복사 하여 수정한다.

하지만 slice 배열 같은 경우는 참조에 의한 타입(참조 복사)이기 때문에 원본 배열을 수정한다.

 

즉 slice는 메모리 번지를 넘겼기 때문에 그 주소가 동일하다.


| slice 배열의 중요한 점

package main

func main() {
	//슬라이스 추가 및 병합

	//길이5, 용량5 slice 배열 선언
	s1 := []int{1, 2, 3, 4, 5}

	//첫 번째 매개변수 : 수정할 배열 변수
	//2,3,4 ... 매개변수 : appen할 data들
	s1 = append(s1, 6, 7)

}

 

위 코드는 문제 없이 정상적으로 작동하는 코드이다.

 

 

하지만, 

 

s1 = append(s1,6,7,8,9,10,11,12)

 


이런식으로 data를 용량을 벗어나게 넣으면 어떻게 될까?

 

바로 퍼포먼스 이슈가 생깁니다.

 

용량을 초과하면, 처음 설정되어있던 용량의 2배를 새로운 배열을 다시 할당후 다시 s1으로 할당해서 내부적으로 만들어집니다.

 

만약 몇 만개의 data를 넣는 작업이 수행된다면 용량을 늘리고, 재할당을 하고 다시 또 슬라이스 배열에 할당하는 작업은 엄청난 리스크입니다.

 

 

| slice 배열 추출 후 병합

	s1 := []int{1, 2, 3, 4, 5}
	s2 := []int{6,7,8,9,}

	//slice배열에 slice를 결합하는 경우 " ... " 을 사용한다.
	s1 = append(s1,s2...)

	//slice배열을 추출 후 병합 하고 싶을 경우
	//index : 0 ~ 2 까지의 slice 배열을 결합
	s1 = append(s1,s2[0:3]...)