본문 바로가기
프로그래밍/Go언어

Golang Array, Slice 사용법. (append)

by Hwan2 2021. 6. 27.
728x90
반응형

 

 

 

Golang에는 Array와 Slice가 있습니다. 

 

Array는 정적 배열, Slice는 동적 배열로 표현됩니다.

 

사실 이 둘의 차이는 선언할 때 배열의 길이를 정해주느냐, 정해주지 않느냐의 차이입니다.

 

하지만 이 차이가 정적과 동적 배열을 결정하게 됩니다.

 

1. Array

 

package main

import "fmt"

func main() {
	var arr1 [5]int = [5]int{1, 2, 3, 4, 5}
	var arr2 = [3]int{1, 2, 3}
	arr3 := [4]int{1, 2, 3, 4}

	fmt.Println(arr1) //output : [1, 2, 3, 4, 5]
	fmt.Println(arr2) //output : [1, 2, 3]
	fmt.Println(arr3) //output : [1, 2, 3, 4]

	arr1 = append(arr1, 6) //error!!
   	arr1 = append(arr1[0:3]) //error!!
    
	sub_arr := append(arr1[0:3])	//[1, 2, 3]
}

Array 선언 방법은 간단하게 위와 같이 나타낼 수 있습니다.

append는 배열 뒤에 값을 붙이는 함수인데 크기가 정해진 정적 배열은 크기를 유동적으로 늘리거나 줄일 수 없습니다.

하지만 새로운 배열에 자신의 배열 요소를 잘라서 전달해 줄 수 있죠.

 

 

2. Slice

 

package main

import "fmt"

func main() {
	var arr1 []int = []int{1, 2, 3, 4, 5}
	var arr2 = []int{1, 2, 3}
	arr3 := []int{1, 2, 3, 4}

	fmt.Println(arr1) //output : [1, 2, 3, 4, 5]
	fmt.Println(arr2) //output : [1, 2, 3]
	fmt.Println(arr3) //output : [1, 2, 3, 4]

	arr1 = append(arr1[0:3])
	arr2 = append(arr2, 100)

	fmt.Println(arr1)	//output : [1, 2, 3]
	fmt.Println(arr2)	//output : [1, 2, 3, 100]
}

 

Slice는 정적 배열과 다르게 그냥 대괄호('[ ]') 안에 아무것도 정해주지 않으면 됩니다.

append를 통해 늘리거나 줄이거나 할 수 있게되죠.

 

 

3. append

Golang의 append 기능은 배열을 자르거나, 지우거나, 추가하거나 할 수 있는 기능들이 있습니다.

그리고 존나 빠릅니다......

우선 0 ~ 100,000,000 배열에 랜덤함 값을 넣은 후 시간을 측정해보고,

append로 1,000번째 있는 요소를 없에 보도록 하겠습니다.

 

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	arr := []int{}
	rand.Seed(time.Now().UnixNano())
	startTime := time.Now()

	for i := 0; i < 100000000; i++ {
		arr = append(arr, rand.Int())
	}

	elapsedTime := time.Since(startTime)
	fmt.Printf("실행시간: %s\n", elapsedTime.Seconds())

	println(&arr)
	startTime = time.Now()
	arr = append(arr[:999], arr[1000:100000000]...)
	elapsedTime = time.Since(startTime)
	fmt.Printf("실행시간: %s\n", elapsedTime.Seconds())
	println(&arr)

}

output :

랜덤한 값들을 배열에 1억개를 넣는데 2초밖에 안걸렸으며, append를 통해 자를때는 0.07초 밖에 안걸렸습니다....

 

go test 명령어를 통한 Benchmark를 돌려보고 싶었는데, 잘 안되서 못했습니다.....

여튼 이를 통해 알 수 있는 것은

 

1. 주소값이 동일하다.

2. 배열 중간값을 지워도 엄청 빠르다.

 

즉, append를 사용하면서 time complexity를 신경을 쓸 필요가 없습니다.

 

그럼 본격 적으로 append 사용법과 배열의 Colon(":")에 대해 알아보도록 합시다.

 

우선 Colon은 배열의 범위를 지정해주는 역할을 합니다.

 

package main

import "fmt"

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

	fmt.Println(arr[2:5]) // output : [3, 4, 5]
	fmt.Println(arr[:3])  // output : [1, 2, 3]
	fmt.Println(arr[3:])  // output : [4, 5]
}

 

저런식으로 배열을 짤라서 반환할 수 있으며, 앞이나 뒤가 생략되면 해당 배열의 첫번째나 끝을 나타내게 됩니다.

 

append는 배열에 값을 추가시켜주는 기능을 제공합니다.

 

사용법은 append(붙일 배열, 추가할 값들) 입니다.

 

package main

import "fmt"

func main() {
	arr := []int{1, 2, 3, 4, 5}
	arr2 := []int{10, 20, 30}

	arr = append(arr, 100)               // output : [1, 2, 3, 4, 5, 100]
	arr3 := append(arr, arr2[0], arr[1]) // output : [1, 2, 3, 4, 5, 100, 10, 20]
	arr4 := append(arr, arr2...)         // output : [1, 2, 3, 4, 5, 100, 10, 20, 30]
	arr5 := append(arr[:2], arr[3:]...)  // output : [1, 2, 4, 5, 100]
	fmt.Println(arr)                     // output : [1, 2, 4, 5, 100, 100]
}

 

여기서 arr5랑 arr를 보도록 하겠습니다.

 

append(arr[:2], arr[3:]...) 로 되어있는데, 이는 

1. arr[0] ~ [1] 까지 자른 부분부터 시작한다.

2. arr[3] ~ 끝까지를 잘라서 앞에 배열에 이어 붙인다.

(여기서 "..."(spread)는 그 다음을 의미하는 뜻으로 사용 됩니다. append는 2번째 인자부턴 배열이 아닌 일반 변수가 들어오게 되어 있거든요.)

3. 이를 arr5로 반환한다.

 

가 됩니다. 주소 값을 찍어보면 서로 다른 주소가 할당된 것을 알 수 있습니다.

 

arr같은 경우 arr5에 값을 넘겨주면 해당 배열의 데이터는 깨지게 됩니다. 이는 내부적으로 포인터로 token과정에서

일어나는 현상 같은걸로 추측됩니다.

때문에, 공식 golang의 append부분을 보면 "경우에 따라서 합친 문자열은 보유하고 있는 배열에 저장해야됩니다." 라고 나와 있습니다.

 

또한 append같은 경우 컴파일러가 상황에 따라서 기존 배열에 추가할지, 새로 메모리를 할당해서 배열을 추가할지 결정 합니다. 

 

https://golang.google.cn/pkg/builtin/#append

 

builtin - The Go Programming Language

Package builtin import "builtin" Overview Index Overview ▹ Overview ▾ Package builtin provides documentation for Go's predeclared identifiers. The items documented here are not actually in package builtin but their descriptions here allow godoc to pres

golang.google.cn

 

 

 

그 외 golang에서 배열에 대해 값을 지우고 싶다면 해당 링크를 참고해 주세요.

https://stackoverflow.com/questions/37334119/how-to-delete-an-element-from-a-slice-in-golang

 

How to delete an element from a Slice in Golang

fmt.Println("Enter position to delete::") fmt.Scanln(&pos) new_arr := make([]int, (len(arr) - 1)) k := 0 for i := 0; i < (len(arr) - 1); { if i != pos { new_arr[i] = arr[k] ...

stackoverflow.com

 

 

 

 

반응형

댓글


스킨편집 -> html 편집에서