Go의 무 탐지
Go에서 다음과 같이 nil을 감지하는 많은 코드가 있습니다.
if err != nil {
// handle the error
}
그러나 다음과 같은 구조체가 있습니다.
type Config struct {
host string
port float64
}
그리고 config는 Config의 인스턴스입니다.
if config == nil {
}
컴파일 오류가 발생했습니다 : nil을 Config 유형으로 변환 할 수 없습니다.
컴파일러가 오류를 가리키고 있습니다. 구조 인스턴스와 nil을 비교하고 있습니다. 그것들은 같은 타입이 아니기 때문에 그것을 잘못된 비교로 간주하고 당신에게 소리칩니다.
여기서하려는 것은 구성 인스턴스에 대한 포인터를 nil과 비교하는 것입니다. 이는 유효한 비교입니다. 그렇게하려면 golang 새 내장을 사용하거나 포인터를 초기화하십시오.
config := new(Config) // not nil
또는
config := &Config{
host: "myhost.com",
port: 22,
} // not nil
또는
var config *Config // nil
그럼 당신은 확인할 수 있습니다
if config == nil {
// then
}
Oleiade 외에도 제로 값에 대한 사양을 참조하십시오 .
선언 또는 make 또는 new 호출을 통해 값을 저장하기 위해 메모리가 할당되고 명시적인 초기화가 제공되지 않으면 메모리에 기본 초기화가 제공됩니다. 이러한 값의 각 요소는 해당 유형의 0 값으로 설정됩니다. 부울의 경우 false, 정수의 경우 0.0, 부동 소수점의 경우 0.0, 문자열의 경우 "", 포인터, 함수, 인터페이스, 슬라이스, 채널 및 맵의 경우 nil. 이 초기화는 재귀 적으로 수행되므로 예를 들어 값을 지정하지 않으면 구조체 배열의 각 요소에는 필드가 0이됩니다.
보시다시피, nil
모든 유형의 0 값이 아니라 포인터, 함수, 인터페이스, 슬라이스, 채널 및 맵의 경우에만 0입니다. 이것이 왜 config == nil
오류이고 &config == nil
그렇지 않은 이유 입니다 .
당신의 구조체가 (예를 들어, 당신은 각각의 제로 값에 대해 모든 구성원을 확인해야 할 것 초기화되지 않은되어 있는지 여부를 확인하려면 host == ""
, port == 0
등) 또는 내부 초기화 방법에 의해 설정되는 개인 필드가 있습니다. 예:
type Config struct {
Host string
Port float64
setup bool
}
func NewConfig(host string, port float64) *Config {
return &Config{host, port, true}
}
func (c *Config) Initialized() bool { return c != nil && c.setup }
내가 생각할 수있는 다양한 방법을 사용하여 새 변수를 만드는 샘플 코드를 만들었습니다. 처음 세 가지 방법으로 값을 만들고 마지막 두 가지 방법으로 참조를 만듭니다.
package main
import "fmt"
type Config struct {
host string
port float64
}
func main() {
//value
var c1 Config
c2 := Config{}
c3 := *new(Config)
//reference
c4 := &Config{}
c5 := new(Config)
fmt.Println(&c1 == nil)
fmt.Println(&c2 == nil)
fmt.Println(&c3 == nil)
fmt.Println(c4 == nil)
fmt.Println(c5 == nil)
fmt.Println(c1, c2, c3, c4, c5)
}
어떤 출력 :
false
false
false
false
false
{ 0} { 0} { 0} &{ 0} &{ 0}
당신은 또한 같은 확인할 수 있습니다 struct_var == (struct{})
. 이를 통해 nil과 비교할 수는 없지만 초기화되었는지 여부를 확인합니다. 이 방법을 사용하는 동안주의하십시오. 구조체가 모든 필드에 대해 0 값 을 가질 수 있다면 좋은 시간이 없습니다.
package main
import "fmt"
type A struct {
Name string
}
func main() {
a := A{"Hello"}
var b A
if a == (A{}) {
fmt.Println("A is empty") // Does not print
}
if b == (A{}) {
fmt.Println("B is empty") // Prints
}
}
http://play.golang.org/p/RXcE06chxE
언어 스펙 비교 연산자 '행동을 언급한다 :
In any comparison, the first operand must be assignable to the type of the second operand, or vice versa.
A value x is assignable to a variable of type T ("x is assignable to T") in any of these cases:
- x's type is identical to T.
- x's type V and T have identical underlying types and at least one of V or T is not a named type.
- T is an interface type and x implements T.
- x is a bidirectional channel value, T is a channel type, x's type V and T have identical element types, and at least one of V or T is not a named type.
- x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type.
- x is an untyped constant representable by a value of type T.
참고URL : https://stackoverflow.com/questions/20240179/nil-detection-in-go
'programing tip' 카테고리의 다른 글
이 임의의 값에 50/50 대신 25/75 분포가있는 이유는 무엇입니까? (0) | 2020.06.21 |
---|---|
파이썬에서 쉼표로 구분 된 문자열을 목록으로 변환하는 방법은 무엇입니까? (0) | 2020.06.21 |
트레이 아이콘 만있는 WPF 응용 프로그램 (0) | 2020.06.21 |
순환 데이터 세트의 평균을 어떻게 계산합니까? (0) | 2020.06.21 |
모카와 차이로 약속을 올바르게 테스트하려면 어떻게해야합니까? (0) | 2020.06.21 |