연습 - 맵 사용
Go의 맵은 기본적으로 키/값 쌍의 컬렉션인 해시 테이블입니다. 맵의 모든 키는 동일한 형식이어야 하므로 값도 마찬가지입니다. 그러나 키 및 값에는 다른 형식을 사용할 수 있습니다. 예를 들어, 키는 숫자일 수 있으며 값은 문자열일 수 있습니다. 맵의 특정 항목에 액세스하려면 해당 키를 참조합니다.
맵 선언 및 초기화
맵을 선언하려면 map
키워드를 사용해야 합니다. 그런 다음, 키와 값 형식을 정의합니다(예: map[T]T
). 예를 들어, 학생의 나이가 포함된 맵을 만들려는 경우 다음 코드를 사용할 수 있습니다.
package main
import "fmt"
func main() {
studentsAge := map[string]int{
"john": 32,
"bob": 31,
}
fmt.Println(studentsAge)
}
위의 코드를 실행하면 다음과 같은 출력이 표시됩니다.
map[bob:31 john:32]
항목을 사용하여 맵을 초기화하지 않으려는 경우 기본 제공 make()
함수를 사용하여 이전 섹션에서 맵을 만들 수 있습니다. 다음 코드를 사용하여 빈 맵을 만들 수 있습니다.
studentsAge := make(map[string]int)
맵은 동적입니다. 항목을 만든 후 추가, 액세스 또는 제거할 수 있습니다. 이러한 작업을 살펴보겠습니다.
항목 추가
항목을 추가하려면 조각을 사용할 때처럼 기본 제공 함수를 사용할 필요가 없습니다. 맵은 좀 더 간단합니다. 키와 값을 정의하기만 하면 됩니다. 쌍이 없으면 항목이 맵에 추가됩니다.
make
함수를 사용하여 맵을 만들기 위해 이전에 사용한 코드를 다시 작성해 보겠습니다. 그런 다음, 맵에 항목을 추가합니다. 다음 코드를 사용할 수 있습니다.
package main
import "fmt"
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
fmt.Println(studentsAge)
}
코드를 실행할 때 이전과 같은 출력을 얻게 됩니다.
map[bob:31 john:32]
초기화된 맵에 항목을 추가했습니다. 그러나 nil
맵으로 동일한 작업을 수행하려고 하면 오류가 발생합니다. 예를 들어, 다음 코드는 작동하지 않습니다.
package main
import "fmt"
func main() {
var studentsAge map[string]int
studentsAge["john"] = 32
studentsAge["bob"] = 31
fmt.Println(studentsAge)
}
위의 코드를 실행하면 다음 오류가 표시됩니다.
panic: assignment to entry in nil map
goroutine 1 [running]:
main.main()
/Users/johndoe/go/src/helloworld/main.go:7 +0x4f
exit status 2
맵에 항목을 추가할 때 문제가 발생하지 않도록 하려면 이전 코드 조각에 표시된 것과 같은 make
함수를 사용하여 빈 맵(nil
맵 아님)을 만들어야 합니다. 이 규칙은 항목을 추가할 때만 적용됩니다. nil
맵에서 조회, 삭제 또는 루프 작업을 실행하는 경우에는 Go에 아무런 문제도 발생하지 않습니다. 잠시 후에 동작을 확인합니다.
항목 액세스
맵의 항목에 액세스하려면 배열 또는 조각과 같이 일반적인 아래 첨자 표기법 m[key]
를 사용합니다. 항목에 액세스하는 방법에 대한 간단한 예제는 다음과 같습니다.
package main
import "fmt"
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
fmt.Println("Bob's age is", studentsAge["bob"])
}
맵에서 아래 첨자 표기법을 사용하는 경우 키가 맵에 없는 경우에도 항상 응답을 받게 됩니다. 존재하지 않는 항목에 액세스하는 경우 Go에 아무런 문제도 발생하지 않습니다. 대신 기본값을 다시 가져옵니다. 다음 코드를 사용하여 동작을 확인할 수 있습니다.
package main
import "fmt"
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
fmt.Println("Christy's age is", studentsAge["christy"])
}
위의 코드를 실행하면 다음과 같은 출력이 표시됩니다.
Christy's age is 0
대부분의 경우 맵에 없는 항목에 액세스하는 경우 Go에서 오류를 반환하지 않습니다. 그러나 항목이 있는지 여부를 알아야 하는 경우가 있습니다. Go에서 맵의 아래 첨자 표기법은 두 값을 생성할 수 있습니다. 첫 번째 값은 항목의 값입니다. 두 번째는 키가 있는지 여부를 나타내는 부울 플래그입니다.
마지막 코드 조각의 문제를 해결하려면 다음 코드를 사용할 수 있습니다.
package main
import "fmt"
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
age, exist := studentsAge["christy"]
if exist {
fmt.Println("Christy's age is", age)
} else {
fmt.Println("Christy's age couldn't be found")
}
}
위의 코드를 실행하면 다음과 같은 출력이 표시됩니다.
Christy's age couldn't be found
두 번째 코드 조각을 사용하여 액세스하기 전에 맵의 키가 있는지 여부를 확인합니다.
항목 제거
맵에서 항목을 제거하려면 기본 제공 delete()
함수를 사용합니다. 맵에서 항목을 제거하는 방법의 예제는 다음과 같습니다.
package main
import "fmt"
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
delete(studentsAge, "john")
fmt.Println(studentsAge)
}
이 코드를 실행하면 다음과 같은 출력이 표시됩니다.
map[bob:31]
앞서 말한 것처럼 존재하지 않는 항목을 삭제하려고 하면 Go에서 아무런 문제도 발생하지 않습니다. 이 동작의 예제는 다음과 같습니다.
package main
import "fmt"
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
delete(studentsAge, "christy")
fmt.Println(studentsAge)
}
이 코드를 실행할 때 오류가 발생하지 않으며 다음과 같은 출력이 표시됩니다.
map[bob:31 john:32]
맵의 루프
마지막으로 맵에서 반복하여 프로그래밍 방식으로 모든 항목에 액세스하는 방법을 살펴보겠습니다. 이렇게 하려면 다음 예제와 같이 범위 기반 루프를 사용할 수 있습니다.
package main
import (
"fmt"
)
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
for name, age := range studentsAge {
fmt.Printf("%s\t%d\n", name, age)
}
}
위의 코드를 실행하면 다음과 같은 출력이 표시됩니다.
john 32
bob 31
키와 값 정보를 서로 다른 변수에 저장할 수 있는 방법을 알아봅니다. 이 경우 name
변수에 키를 저장하고 age
변수에 값을 저장합니다. 따라서 range
는 먼저 항목의 키를 생성하고 그 다음에는 해당 항목의 값을 생성합니다. 다음 예제와 같이 _
변수를 사용하여 둘 중 하나를 무시할 수 있습니다.
package main
import (
"fmt"
)
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
for _, age := range studentsAge {
fmt.Printf("Ages %d\n", age)
}
}
이 경우에는 이 방법으로 나이를 출력하는 것이 적절하지 않지만 항목의 키를 알 필요가 없는 경우가 있습니다. 또는 다음 예제와 같이 항목의 키만 사용할 수 있습니다.
package main
import (
"fmt"
)
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
for name := range studentsAge {
fmt.Printf("Names %s\n", name)
}
}