development

데이터 (유형 인터페이스 {})를 유형 문자열로 변환 할 수 없음 : 유형 어설 션 필요

big-blog 2020. 6. 6. 07:56
반응형

데이터 (유형 인터페이스 {})를 유형 문자열로 변환 할 수 없음 : 유형 어설 션 필요


나는 꽤나 새로 왔으며이 알림 패키지를 가지고 놀고있었습니다 .

처음에는 다음과 같은 코드가있었습니다.

func doit(w http.ResponseWriter, r *http.Request) {
    notify.Post("my_event", "Hello World!")
    fmt.Fprint(w, "+OK")
}

Hello World!의 함수에는 개행 문자를 추가하고 싶었습니다 doit. 왜냐하면 꽤 간단 하기는하지만 handler나중에 다음과 같이하기 때문입니다.

func handler(w http.ResponseWriter, r *http.Request) {
    myEventChan := make(chan interface{})
    notify.Start("my_event", myEventChan)
    data := <-myEventChan
    fmt.Fprint(w, data + "\n")
}

go run:

$ go run lp.go 
# command-line-arguments
./lp.go:15: invalid operation: data + "\n" (mismatched types interface {} and string)

약간의 인터넷 검색 후 나는 이 질문을 SO 에서 발견 했다 .

그런 다음 코드를 다음과 같이 업데이트했습니다.

func handler(w http.ResponseWriter, r *http.Request) {
    myEventChan := make(chan interface{})
    notify.Start("my_event", myEventChan)
    data := <-myEventChan
    s:= data.(string) + "\n"
    fmt.Fprint(w, s)
}

이것이 내가해야했던 일입니까? 컴파일러 오류가 사라 졌으므로 꽤 좋을 것 같습니다. 이것이 효율적입니까? 다르게해야합니까?


Go 사양 에 따르면 :

인터페이스 유형의 표현식 x와 유형 T의 경우, 기본 표현식 x. (T)는 x가 nil이 아니며 x에 저장된 값이 T 유형임을 주장합니다.

"유형 어설 션"을 사용하면 인터페이스 값에 특정 콘크리트 유형이 포함되어 있거나 콘크리트 유형이 다른 인터페이스를 충족한다고 선언 할 수 있습니다.

귀하의 예에서 데이터를 주장하고 있었으며 (type interface {}) 콘크리트 유형 문자열이 있습니다. 당신이 잘못되면, 프로그램은 런타임에 패닉합니다. 효율성에 대해 걱정할 필요가 없습니다. 검사는 두 개의 포인터 값을 비교하기 만하면됩니다.

문자열인지 확실하지 않은 경우 두 반환 구문을 사용하여 테스트 할 수 있습니다.

str, ok := data.(string)

데이터가 문자열이 아닌 경우 ok는 false입니다. 그런 다음과 같은 명령문을 if 문으로 랩핑하는 것이 일반적입니다.

if str, ok := data.(string); ok {
    /* act on str */
} else {
    /* not string */
}

유형 어설 션

이것은 type assertiongolang 으로 알려져 있으며 일반적인 관행입니다.

다음은 둘러보기의 설명 입니다 .

형식 어설 션은 인터페이스 값의 기본 구체적인 값에 대한 액세스를 제공합니다.

t := i.(T)

이 명령문은 인터페이스 값 i가 구체적 유형 T를 보유하고 기본 T 값을 변수 t에 지정 한다고 주장합니다 .

내가 T를 보유하지 않으면, 진술은 공황을 유발할 것입니다.

인터페이스 값에 특정 유형이 있는지 여부를 테스트하기 위해 유형 어설 션은 기본 값과 어설 션 성공 여부를보고하는 부울 값의 두 값을 반환 할 수 있습니다.

t, ok := i.(T)

i에 T가 있으면 t가 기본 값이되고 ok가 true가됩니다.

그렇지 않은 경우 ok는 false이고 t는 T 유형의 0 값이며 패닉은 발생하지 않습니다.

참고 : i은 인터페이스 유형이어야합니다 .

함정

Even if i is an interface type, []i is not interface type. As a result, in order to convert []i to its value type, we have to do it individually:

// var items []i
for _, item := range items {
    value, ok := item.(T)
    dosomethingWith(value)
}

Performance

As for performance, it can be slower than direct access to the actual value as show in this stackoverflow answer.


//an easy way:
str := fmt.Sprint(data)

참고URL : https://stackoverflow.com/questions/14289256/cannot-convert-data-type-interface-to-type-string-need-type-assertion

반응형