Golang_기초 7 (배열, 슬라이스, 맵)

아따맘마·2021년 11월 16일
0

배열

배열은 C언어와 같이 인덱스는 0에서부터 시작.

package main

import "fmt"

func main() {
	var a [5]int
	a[2] = 7
	fmt.Println(a)
}

배열을 만들 때 자료형 앞에 []을 붙이고 길이를 설정. 배열 생성 시 모두 0으로 초기화된다.
값을 초기화할 때 {}를 사용한다.

package main

import "fmt"

func main() {
	var a [5]int = [5]int{1, 2, 3, 4, 5}
	c := [5]int{10, 20, 30, 40, 50}

	fmt.Println(a)
	fmt.Println(c)
}

:=을 사용하면 좀 더 간편하게 배열 생성 가능하다.

d := [...]int{1, 2, 3, 4, 5, 6}

위와 같이 []안에 ...을 삽입하면 초기화한 값 개수에 따라 크기를 결정해준다.

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

다차원 배열도 생성 가능. 한줄이 아닌 여러줄로 초기화할 시 마지막 값에도 ,를 붙여준다.
배열의 길이는 len으로 알 수 있다.

d := [...]int{1, 2, 3, 4, 5, 6}
fmt.Println(len(d))

배열의 요소를 가져올 때 for에 len이 아닌 range를 사용해서 간단하게 가져올 수 있다. 하지만 이는 인덱스와 값을 같이 출력.

	var a [5]int = [5]int{1, 2, 3, 4, 5}
    
	for i, value := range a {
		fmt.Println(i, value)
	}

이 때 i 대신 _을 사용하면 인덱스는 제외하고 값만 출력 가능

	var a [5]int = [5]int{1, 2, 3, 4, 5}
    
	for _, value := range a {
		fmt.Println(value)
	}

슬라이스

슬라이스는 배열과 비슷하지만 차이점은 길이가 고정되어있지 않으며 동적으로 크기가 늘어난다.
배열과 달리 레퍼런스 타입이다.

package main

import "fmt"

func main() {
	var a []int = make([]int ,5)
	b := make([]int, 6)
}

슬라이스 생성시 모두 0으로 초기화되고, 값을 초기화할 시 배열처럼 {]을 사용.

c := make([]int, 5, 10)

슬라이스는 배열을 내장하고 있는데, 이 배열이 늘어났을 때 사용할 공간을 미리 할당 가능.

  • make([]자료형, 길이, 용량)

위 코드를 실행하면 길이가 5, 용량이 10인 슬라이스 생성.
길이는 용량보다 클 수 없고, 용량을 생략하면 용량은 길이오 동일.

  • 길이 : 인덱스로 접근할 수 있는 공간 (슬라이스 내부 배열의 최대 길이). 용량이 더 확보되어 있더라도 길이 이상의 인덱스에 접근하면 런타임 에러 발생.

  • 용량 : 실제 메모리에 할당된 공간. 슬라이스에 요소를 추가하여 용량이 가득차면 용량은 자동적으로 늘어난다.

슬라이스에 값 추가

append함수를 사용하여 슬라이스 맨 뒤에 값을 추가할 수 있다.

package main

import "fmt"

func main() {
	a := []int{1, 2, 3}
	a = append(a, 4, 5, 6)
	fmt.Println(a)
}

슬라이스에 다른 슬라이스를 붙이려면 append을 사용할 때 ...을 쓴다.

package main

import "fmt"

func main() {
	a := []int{1, 2, 3}
	b := []int{3, 4, 5, 6}
	a = append(a, b...)

	fmt.Println(a)
}

레퍼런스 타입

슬라이스는 레퍼런스 타입인데 이는 내장된 배열에 대한 포인터이므로 슬라이스끼리 대입하면 값이 복사되지 않고 참조만 한다.
우선 배열은

package main

import "fmt"

func main() {
	a := [3]int{1, 2, 3}
	var b [3]int

	b = a
	b[0] = 9

	fmt.Println(a)
	fmt.Println(b)
}

위 코드를 실행하면 a는 [1 2 3], b는 [9 2 3]이 출력. b에는 a의 값이 대입됬다는걸 증명한다.
이에 반해 슬라이스는

package main

import "fmt"

func main() {
	a := []int{1, 2, 3}
	var b []int

	b = a
	b[0] = 9

	fmt.Println(a)
	fmt.Println(b)
}

a더 [9 2 3], b도 [9 2 3]이 출력된다. 슬라이스를 대입할 때 참조되므로 a, b 모두 바뀐다.
함수의 매개변수로 배열을 넘기면 복사가 되지만 슬라이스를 넘기면 참조만 한다. 함수 안에서 슬라이스의 요소를 변경하면 바깥에 있는 슬라이스도 값이 바뀐다.

요소를 복사하고 싶을 때는 copy를 사용한다.

  • copy(복사될 슬라이스, 원본 슬라이스)

맵은 해시 테이블, 딕셔너리라고도 하며 Key-Value 형태로 자료를 저장. 맵도 레퍼런스 타입이다.

var a map[string]int
b := make(map[string]int]

이는 Key : string, Value : int 인 맵을 선언
초기화할때 마찬가지로 {}를 사용

맵에 키가 존재하는지 확인하려면 리턴값을 두개 활용

a, b := mapping["abc"]

키가 있으면 두번째 리턴값으로 false, 존재하면 true를 반환한다.

profile
늦게 출발했지만 꾸준히 달려서 도착지점에 무사히 도달하자

0개의 댓글