2024.03.19
var x = [3]int{10, 20, 30}
var x = [12]int{1, 5: 4, 6, 10: 100, 15}
// [1, 0, 0, 0, 0, 4, 6, 0, 0, 0, 100, 15]
var x = []int{10, 20, 30}
var x []int
nil
이라는 값이다.nil
은 몇몇 타입의 값의 부재를 표현한 식별자이다.nil
인 것은 어떤 요소도 갖고 있지 않다는 것이다.==
연산자를 사용하거나 !=
사용하면 컴파일 오류가 발생한다.nil
으로만 비교가 가능하다.fmt.Println(x == nil) // true를 출력
len
으로 슬라이스의 길이를 알 수 있다.nil
값을 가진 슬라이스를 len
으로 전달하면 0을 반환한다.append
함수는 슬라이스에 새로운 요소를 추가한다.var x []int
x = append(x, 10)
x = append(x, 4, 5, 6)
...
연산자를 이용해 다른 슬라이스의 개별 요소들을 추가하여 확장할 수도 있다.y := []int{20, 30, 40}
x = append(x, y...)
append
를 통해 반환된 값을 할당하지 않는다면 컴파일 오류가 날 것이다. Go는 값에 의한 호출(call by value) 방식을 사용하는 언어이기 때문이다.append
로 전달된 슬라이스는 복사된 값이 함수로 전달된다. 이 함수는 복사된 슬라이스에 값들을 추가하고 추가된 복사본을 반환한다. 그렇기 때문에 함수 호출에 사용한 변수에 반환된 슬라이스를 다시 할당해 줘야 한다.슬라이스의 각 요소는 연속적인 메모리 공간에 할당될 것이고, 이런 할당은 값을 빠르게 읽고 쓰기가 가능하도록 한다. 모든 슬라이스는 수용력(capacity)을 가지는데, 예약된 연속적인 메모리 공간의 크기 값을 가진다.
슬라이스에 하나 혹은 하나 이상의 값들을 추가할 때, 슬라이스의 뒤쪽에서 부터 채워진다. 추가된 각 값에 따라 슬라이스의 길이가 1씩 증가한다.
길이가 수용할 만큼 증가한다면, 더 이상 값을 넣을 공간이 없게된다. 길이와 수용력이 같아진 시점에 값을 추가한다면, append
는 Go 런타임을 사용하여 더 큰 수용력을 가지는 새로운 슬라이스를 할당한다.
Go 런타임이 슬라이스의 수용력이 다 차면 대개 기존 수용력의 두 배만큼 증가시킨다.
내장 함수 cap
함수는 현재 슬라이스의 수용력을 반환환다. 대부분 cap
의 사용은 새로운 데이터를 들이기에 충분한 공간이 슬라이스에 있는지를 확인하는 용도로 사용되거나 새로운 슬라이스를 할당하기 위해 make
함수를 호출하는 경우에 사용된다.
make
는 타입, 길이, 그리고 선택적으로 수용력을 지정하여 슬라이스를 만들 수 있다.x := make([]int, 5)
// 길이 5, 수용력 5를 가지는 정수 슬라이스를 만든다.
// 길이가 5이기 때문에 x[0]에서 x[4]까지 접근 가능한 요소이며, 모두 0으로 초기화된다.
x := make([]int, 5, 10)
// 길이 5, 수용력 10를 가지는 정수 슬라이스를 만든다.
nil
슬라이스를 만들기 위해 값의 할당이 없는 var
선언을 사용하자.make
를 사용해보자.make
사용하여 슬라이스를 선언하는 방식으로 나뉜다.x := []int{1, 2, 3, 4}
y := x[:2]
z := x[1:]
d := x[1:3]
e := x[:]
// x [1 2 3 4]
// y [1 2]
// z [2 3 4]
// d [2 3]
// e [1 2 3 4]
append
와 함께 사용하면 혼란이 가중된다.x := []int{1, 2, 3, 4}
y := x[:2]
fmt.Println(cap(x), cap(y))
y = append(y, 30)
fmt.Println("x:", x)
fmt.Println("y:", y)
// 4 4
// x: [1 2 30 4]
// y: [1 2 30]
append
를 사용하지 않거나 append
를 사용해도 덮어쓰기가 되지 않도록 하는 완전한 슬라이스 연산(full slice expression)을 사용하도록 하자.y := x[:2:2]
x := [4]int{5, 6, 7, 8}
y := x[:2]
// x [10 6 7 8]
// y [10 6]
copy
를 사용하자.copy
함수는 2개의 파라미터를 가진다. 첫 번째는 대상 슬라이스고, 두 번째는 원본 슬라이스이다.x := []int{1, 2, 3, 4}
y := make([]int, 4)
num := copy(y, x)
// y [1 2 3 4]
// num 4
x := []int{1, 2, 3, 4}
y := make([]int, 2)
num := copy(y, x)
// y [1 2]
// num 2
x := []int{1, 2, 3, 4}
y := make([]int, 2)
num := copy(y, x[2:])
// y [3 4]
// num 2
var s string = "Hello there"
var b byte = s[6] // t
var c string = s[4:7] // "o t"
var d string = s[:5] // "Hello"
var e string = s[6:] // "there"
len
에 문자열을 넘겨, 문자열의 길이를 파악할 수 있다.len
을 통해 반환된 길이는 코드 단위가 아니라 바이트 단위라는 것을 알 수 있다.var s string = "Helllo 😃"
fmt.Println(len(s))
// 7이 아닌 10을 출력한다. 이모티콘을 표현하기 위해 4바이트를 사용하였기 때문에,
var a rune = 'x'
var s string = string(a)
var b byte = 'y'
var s2 string = string(b)
var q string = "Hello, 😃"
var bs []byte = []byte(s)
var rs []rune = []rune(s)
// bs [72 101 108 108 111 44 32 240 159 140 158]
// rs [72 101 108 108 111 44 32 127774]
var nilMap map[string]int
// 길이 0, 제로 값은 nil, 맵에 값을 쓰려고 한다면 패닉 발생
totalWins := map[string]int{}
// 길이 0, 맵은 비어 있지만 맵의 값을 읽고 쓸 수 있음
teams := map[string][]string {
"Orcas": []string{"Fred", "Ralph"},
"Lions": []string{"Sarah", "Peter"},
}
// 비어 있지 않은 맵 리터럴
make
를 이용해서 기본 크기를 지정하여 맵을 생성할 수 있다.ages := make(map[int][]string, 10)
len
함수에 맵을 넘긴다면 키-값 쌍이 맵에 몇 개가 있는지를 알려준다.nil
이다.nil
과는 비교가 가능하다.m := map[string]int{
"hello": 5,
"world": 0,
}
v, ok := m["hello"]
fmt.Println(v, ok)
v, ok := m["world"]
fmt.Println(v, ok)
v, ok := m["goodbye"]
fmt.Println(v, ok)
// 5 true
// 0 true
// 0 false
delete
를 이용하여 맵에서 삭제될 수 있다.m := map[string]int{
"hello": 5,
"world": 0,
}
delete(m, "hello") // 해당 키-값 쌍이 제거된다.
delete(m, "goodbye") // 아무 일도 일어나지 않는다.
sturct
를 정의하여 사용할 수 있다.type
키워드로 구조체 타입의 이름을 지정하고, 키워드 struct
다음에 중괄호({}
)로 구조체를 정의할 수 있다.type person struct {
name string
age int
pet string
}
julia := person{
"Julia",
40,
"cat",
}
// 구조체 항목 순서대로 값들을 나열해야 한다.
beth := person{
age: 30,
name: "Beth",
}
// 순서와 상관없이 항목의 값을 넣을 수 있다.
// 특정 항목을 빼도 된다.
var person struct {
name string
age int
pet string
}
person.name = "bob"
pet := struct {
name string
kind string
}{
name: "Fido",
kind: "dog",
}