답변:
한 줄 답변 :
if val, ok := dict["foo"]; ok {
//do something here
}
if
Go의 문장에는 조건문과 초기화 문장이 모두 포함될 수 있습니다. 위의 예는 다음을 모두 사용합니다.
두 변수를 초기화 val
합니다.지도에서 "foo"값을 받거나 "제로 값"(이 경우 빈 문자열) ok
을 받고 true
"foo"가 실제로지도에있는 경우 설정되는 부울을받습니다.
"foo"가지도에 ok
있는 true
경우 평가 됩니다.
"foo"가 실제로 맵에 존재하면 if
명령문 의 본문 이 실행되고 val
해당 범위에 로컬이됩니다.
var val string = ""
은 동일하게 유지 val, ok :=
되며 해당 블록에서만 보이는 동일한 이름을 가진 새로운 지역 변수를 만듭니다.
if key in dict
.
Go 프로그래밍 언어 사양 외에도 Effective Go를 읽어야 합니다 . 지도 섹션에서 다음 과 같이 말합니다.
맵에없는 키로 맵 값을 가져 오려고하면 맵의 항목 유형에 대한 0 값이 리턴됩니다. 예를 들어, 맵에 정수가 포함 된 경우 존재하지 않는 키를 검색하면 0이 반환됩니다. 값 유형이 bool 인 맵으로 집합을 구현할 수 있습니다. 맵 항목을 true로 설정하여 값을 세트에 넣은 후 간단한 색인 작성으로 테스트하십시오.
attended := map[string]bool{ "Ann": true, "Joe": true, ... } if attended[person] { // will be false if person is not in the map fmt.Println(person, "was at the meeting") }
때로는 누락 된 항목을 0 값과 구별해야합니다. "UTC"에 대한 항목이 있거나지도에 전혀 없기 때문에 0입니까? 여러 과제 형태로 차별 할 수 있습니다.
var seconds int var ok bool seconds, ok = timeZone[tz]
명백한 이유로 이것을 "쉼표 ok"관용구라고합니다. 이 예에서 tz가 있으면 초가 적절하게 설정되고 ok가 true가됩니다. 그렇지 않으면 초가 0으로 설정되고 ok가 false가됩니다. 멋진 오류 보고서와 함께 사용하는 함수는 다음과 같습니다.
func offset(tz string) int { if seconds, ok := timeZone[tz]; ok { return seconds } log.Println("unknown time zone:", tz) return 0 }
실제 값에 대해 걱정하지 않고 맵에서 존재를 테스트하려면 값에 대한 일반적인 변수 대신 공백 식별자 (_)를 사용할 수 있습니다.
_, present := timeZone[tz]
견과류 이메일 목록 에서 검색 한 결과 Peter Froehlich가 2009 년 11 월 15 일에 게시 한 솔루션을 찾았습니다.
package main
import "fmt"
func main() {
dict := map[string]int {"foo" : 1, "bar" : 2}
value, ok := dict["baz"]
if ok {
fmt.Println("value: ", value)
} else {
fmt.Println("key not found")
}
}
또는 더 간결하게
if value, ok := dict["baz"]; ok {
fmt.Println("value: ", value)
} else {
fmt.Println("key not found")
}
이 양식의 if
명령문을 사용하면 value
및 ok
변수는 if
조건 내에서만 볼 수 있습니다 .
_, ok := dict["baz"]; ok
. _
부분은 임시 변수를 만드는 대신 거리 값을 던졌습니다.
_, exists := timeZone[tz] // Just checks for key existence
val, exists := timeZone[tz] // Checks for key existence and retrieves the value
Go Playground 의 예가 있습니다.
맵에없는 키로 맵 값을 가져 오려고하면 맵의 항목 유형에 대한 0 값이 리턴됩니다. 예를 들어,지도에 정수가 포함 된 경우 존재하지 않는 키를 찾으려면 0을 반환합니다.
때로는 누락 된 항목을 0 값과 구별해야합니다. "UTC"에 대한 항목이 있습니까 아니면지도에 전혀 없기 때문에 빈 문자열입니까? 여러 과제 형태로 차별 할 수 있습니다.
var seconds int var ok bool seconds, ok = timeZone[tz]
명백한 이유로 이것을 "쉼표 ok"관용구라고합니다. 이 예에서 tz가 있으면 초가 적절하게 설정되고 ok가 true가됩니다. 그렇지 않으면 초가 0으로 설정되고 ok가 false가됩니다. 멋진 오류 보고서와 함께 사용하는 함수는 다음과 같습니다.
func offset(tz string) int { if seconds, ok := timeZone[tz]; ok { return seconds } log.Println("unknown time zone:", tz) return 0 }
실제 값에 대해 걱정하지 않고 맵에서 존재를 테스트하려면 값에 대한 일반적인 변수 대신 공백 식별자 (_)를 사용할 수 있습니다.
_, present := timeZone[tz]
다른 답변에서 언급 한 바와 같이, 일반적인 솔루션은 사용하는 인덱스 식을 에 할당 특별한 형태의 :
v, ok = a[x]
v, ok := a[x]
var v, ok = a[x]
var v, ok T = a[x]
이것은 좋고 깨끗합니다. 그러나 몇 가지 제한 사항이 있습니다. 특수 양식을 지정해야합니다. 오른쪽 표현식은 맵 인덱스 표현식이어야하며 왼쪽 표현식 목록에는 정확히 2 개의 피연산자가 있어야합니다. 첫 번째는 피연산자가 bool
값을 할당 할 수 있고 두 번째는 피연산자가 값을 할당 할 수있는 것입니다. 이 특수 양식 결과의 첫 번째 값은 키와 연관된 값이며 두 번째 값은 지정된 키를 가진 맵에 실제로 항목이 있는지 여부를 알려줍니다 (키가 맵에있는 경우). 결과 중 하나가 필요하지 않은 경우 왼쪽 표현식 목록에 공백 식별자 도 포함될 수 있습니다 .
인덱싱 된 맵 값이 nil
키를 포함하거나 포함하지 않는 경우 인덱스 식은 맵 값 유형의 0 값 으로 평가 됩니다. 예를 들어 :
m := map[int]string{}
s := m[1] // s will be the empty string ""
var m2 map[int]float64 // m2 is nil!
f := m2[2] // f will be 0.0
fmt.Printf("%q %f", s, f) // Prints: "" 0.000000
Go Playground 에서 사용해보십시오 .
따라서지도에서 0 값을 사용하지 않는 경우이를 활용할 수 있습니다.
예를 들어 값 유형이 string
이고 값이 빈 문자열 ( string
유형의 경우 0 값 ) 인 맵에 항목을 저장하지 않는 경우 비 특수 값을 비교하여 키가 맵에 있는지 테스트 할 수도 있습니다. 인덱스 표현식의 결과 (0의 결과) :
m := map[int]string{
0: "zero",
1: "one",
}
fmt.Printf("Key 0 exists: %t\nKey 1 exists: %t\nKey 2 exists: %t",
m[0] != "", m[1] != "", m[2] != "")
출력 ( Go Playground 에서 시도 ) :
Key 0 exists: true
Key 1 exists: true
Key 2 exists: false
실제로 우리는 0 값을 맵에 저장하지 않는 경우가 많으므로 자주 사용할 수 있습니다. 예를 들어 인터페이스와 함수 유형은 0 값을 가지며, nil
종종 맵에 저장하지 않습니다. 따라서 키가지도에 있는지 테스트하는 것은 키와 비교하여 수행 할 수 있습니다 nil
.
이 "기술"을 사용하면 또 다른 장점이 있습니다. 여러 키가 존재하는지 간단한 방법으로 확인할 수 있습니다 (특별한 "쉼표"형식으로는 수행 할 수 없습니다). 이에 대한 추가 정보 : 한 조건에서 키가 여러 맵에 존재하는지 확인
존재하지 않는 키로 인덱싱 할 때 값 유형의 0 값을 가져 오면 값이있는 맵을 bool
편리하게 세트 로 사용할 수 있습니다 . 예를 들면 다음과 같습니다.
set := map[string]bool{
"one": true,
"two": true,
}
fmt.Println("Contains 'one':", set["one"])
if set["two"] {
fmt.Println("'two' is in the set")
}
if !set["three"] {
fmt.Println("'three' is not in the set")
}
출력합니다 ( Go Playground 에서 시도하십시오 ).
Contains 'one': true
'two' is in the set
'three' is not in the set
T
에 var v, ok T = a[x]
? ok
바보 가 아니 어야합니까?
map[bool]bool
이고 T
is bool
인 경우에만 작동 (컴파일) 할 것이라고 생각할 수도 있지만 map이 type map[interface{}]bool
이고 T
is 인 경우에도 작동합니다 interface{}
. 또한 bool
기본 유형으로 사용되는 사용자 정의 유형에서도 작동합니다 . Go Playground 에서 모두 참조하십시오 . 따라서 해당 형식은로 대체되는 여러 유형으로 유효 T
하므로 일반 T
이 사용되는 이유 입니다. 의 종류는 ok
되는 무엇이든 할 수있다 형식화되지 않은이bool
할당 할 수 있습니다.
더 나은 방법은 여기
if _, ok := dict["foo"]; ok {
//do something here
}
var empty struct{}
var ok bool
var m map[string]struct{}
m = make(map[string]struct{})
m["somestring"] = empty
_, ok = m["somestring"]
fmt.Println("somestring exists?", ok)
_, ok = m["not"]
fmt.Println("not exists?", ok)
그런 다음 maps.go를 실행하십시오. 존재하지 않는가? 그릇된
_, ok = m["somestring"]
해야=_, ok := m["somestring"]
"인덱스 표현식"에 언급되어 있습니다.
특수 양식의 지정 또는 초기화에 사용되는 map [K] V 유형의 맵에서 인덱스 표현식
v, ok = a[x] v, ok := a[x] var v, ok = a[x]
추가 유형화되지 않은 부울 값을 생성합니다. 키 x가 맵에 있으면 ok 값은 true이고, 그렇지 않으면 false입니다.
이 목적으로 두 가지 값을 할당 할 수 있습니다. 아래 샘플 프로그램을 확인하십시오
package main
import (
"fmt"
)
func main() {
//creating a map with 3 key-value pairs
sampleMap := map[string]int{"key1": 100, "key2": 500, "key3": 999}
//A two value assignment can be used to check existence of a key.
value, isKeyPresent := sampleMap["key2"]
//isKeyPresent will be true if key present in sampleMap
if isKeyPresent {
//key exist
fmt.Println("key present, value = ", value)
} else {
//key does not exist
fmt.Println("key does not exist")
}
}