Go 언어에서 함수는 클로저(Closure)로도 사용될 수 있다.
클로저 란 함수 바깥에 있는 변수를 참조하는 함수값을 일컫는데, 이때의 함수는 바깥의 변수를 마치 함수 안으로 끌어들인 듯이 그 변수를 읽거나 쓸 수 있게 된다.
배열은 연속적인 메모리 공간에 동일한 타입의 데이터를 순차적으로 저장하는 자료구조이다.
Go도 자바스크립트와 마찬가지로 zero based array(첫번째 인덱스가 0인) 이다.
배열의 선언은 var 변수명 [배열크기] 데이터타입 과 같이 한다.
배열의 초기값은 [배열크기] 데이터타입 뒤에 괄호 {} 를 두고 초기값을 순서대로 적으면 된다.
만약 초기화 과정에서 [...]을 사용하여 배열의 크기를 생략하면 자동적으로 초기화 요소 숫자만큼 배열의 크기가 정해진다.
var a1 = [3]int{1,2,3}
var a2 = [...]int{1,2,3} // 배열크기 자동으로
var multiArray [3][4][5]int // 정의
multiArray[0][1][2] = 10 // 사용
다차원 배열의 초기화는 단차원 배열의 초기화와 비슷하다.
다만, 다차원이므로 배열 초기값 안에 다시 배열값을 넣는 형태이다.
즉, 아래 코드에서 보듯, 2개의 행과 3개의 열을 이루는 배열이 초기화되었는데, 1행이 {1,2,3} 처럼 묶여서 표현되고 있다.
func main() {
var a = [2][3]int {
{1, 2, 3},
{4, 5, 6}, // 끝에 콤마 추가
}
fmt.Println(a[1][2])
}
Go 슬라이스 선언은 배열 선언하듯이 var v [] T 와 같이 하는데 배열과 달리 크기는 지정하지 않는다.
예를 들어, 정수형 Slice 변수 a를 선언하기 위해서 var a [] int 처럼 선언할 수 있다.
Go 에서 슬라이스를 생성하는 또 다른 방법으로 Go의 내장함수 make() 함수를 이용할 수 있다.
make() 함수를 이용하면, 슬라이스의 길이, 용량을 임의로 지정할 수 있는 장점이 있다.
make() 함수의 첫번째 파라미터에 타입을 지정하고, 두번째에 length, 세번째에 capacity (내부 배열 최대 길이)를 지정하면, 모든 요소가 zero value 인 슬라이스를 만들게 된다.
여기서 만약 세번째 파라미터 capacity를 생략하면 capacity는 length 와 같은 값을 갖는다.
그리고 슬라이스의 길이 및 용량은 내장함수 len(), cap() 를 써서 확인할 수 있다.
슬라이스에 별도의 길이와 용량을 지정하지 않으면, 기본적으로 길이와 용량이 0인 슬라이스를 만드는데, 이를 Nil Slice라고 하고, nil과 비교하면 참을 리턴한다.
부분 슬라이스는 배열[처음인덱스: 마지막인덱스] 형식으로 만드는데, 예를 들어 2에서 4까지 슬라이스한다고 하면, s[2:5] 처럼 만든다. 즉, 마지막 인덱스는 원하는 인덱스 + 1 을 해줘야 한다.
그리고, 슬라이스 인덱스는 처음, 마지막 둘 중 하나 혹은, 둘 다 생략할 수 있다.
처음 인덱스가 생략되면 0이, 마지막 인덱스가 생략되면 슬라이스의 마지막 인덱스가 자동 대입된다.
만약 [:] 과 같이 둘 다 생략하면, 전체를 표현한다.
배열은 고정된 크기로 그 크기 이상의 데이터를 임의로 추가할 수 없지만, 슬라이스는 자유롭게 새로운 요소를 추가할 수 있다.
새로운 요소를 추가하려면 내장함수 append() 를 사용한다.
append()의 첫 파라미터는 슬라이스 객체이고, 두번째는 추가 할 요소의 값이다.
또한 여러 개의 요소 값들을 한꺼번에 추가하려면 append() 두번째 파라미터 뒤에 계속하여 값을 추가하면 된다.
이러한 추가/확장 기능과 더불어, Go 슬라이스는 내장함수 copy()를 사용하여 한 슬라이스를 다른 슬라이스로 복사할 수도 있다.
슬라이스는 실제 배열을 가리키는 포인터 정보만을 가지므로, 복사를 좀 더 정확히 표현하면, 소스 슬라이스가 갖는 배열의 데이터를 타겟 슬라이스가 갖는 배열로 복제하는 것이다.
Map은 키(key)에 대응하는 값(value)을 신속히 찾는 해시테이블을 구현한 자료구조이다.
map[key타입]value타입과 같이 선언할 수 있다.
예를 들어 정수를 키로하고 문자열을 값으로 하는 맵 변수 idMap을 선언하기 위해서 다음과 같이 할 수 있다.
var idMap map[int]string
이때 선언된 변수 idMap은 nil 값을 가지며, 이를 Nil Map 이라 부른다. Nil Map에는 어떤 데이터를 쓸 수 없는데, map을 초기화하기 위해 make() 함수를 쓸 수 있다.
idMap = make(map[int]string)
make() 함수를 써서 초기화할 수도 있지만, 리터럴을 사용해 초기화할 수도 있다.
tickers := map[string]string{
"GOOG" : "Google Inc",
"MSFT" : "Microsoft",
"FB" : "FaceBook",
}
새로운 데이터를 추가하기 위해서는 map변수[키] = 값 과 같이 해당 키에 값을 할당하면 된다.
만약 특정 키에 해당 값이 존재한다면, 추가 대신 값만 갱신한다.
map변수[key] 읽기를 수행할 때 2개의 리턴값을 리턴한다.
첫번째는 키에 상응하는 값이고, 두번째는 그 키가 존재하는지 아닌지를 나타내는 bool 값이다.
func main() {
a := map[string]string{
"GOOG" : "GOOGLE",
"FB" : "FACEBOOK",
"KK": "KAKAO",
}
for key, val := range a {
fmt.Println(key, val)
}
}