veri (tip arayüzü {}) dizgiye dönüştürülemiyor: tür onayı gerekiyor


178

Gitmek için oldukça yeniyim ve bu bildirim paketi ile oynuyordum .

İlk başta şöyle görünüyordu kodu vardı:

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

Newline eklemek istedim Hello World!ama doityukarıdaki fonksiyonda değil , çünkü bu oldukça önemsiz olurdu, ancak handlerdaha sonra aşağıdaki gibi:

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

Sonra go run:

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

Biraz Googling'den sonra bu soruyu SO'da buldum .

Sonra kodumu güncelledim:

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)
}

Yapmam gereken bu muydu? Benim derleyici hataları gitti bu yüzden bu oldukça iyi sanırım? Bu verimli mi? Farklı mı yapmalısın?

Yanıtlar:


292

Göre Git şartname :

Arabirim türü x ve T tipi bir ifade için, birincil ifade x. (T) x'in sıfır olmadığını ve x'te depolanan değerin T tipinde olduğunu belirtir.

"Tip iddiası", bir arayüz değerinin belirli bir beton türü içerdiğini veya beton türünün başka bir arayüzü karşıladığını beyan etmenizi sağlar.

Örneğin, verilerin (tip arabirimi {}) somut bir dize olduğunu iddia ediyordunuz. Yanılıyorsanız, program çalışma zamanında panikleyecektir. Verimlilik konusunda endişelenmenize gerek yok, kontrol sadece iki işaretçi değerinin karşılaştırılmasını gerektirir.

Bir dize olup olmadığından emin değilseniz, iki dönüş sözdizimini kullanarak test edebilirsiniz.

str, ok := data.(string)

Veriler bir dize değilse tamam yanlış olur. Daha sonra böyle bir ifadeyi şöyle bir if ifadesine sarmak yaygındır:

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

29

Tip Beyanı

Bu type assertiongolang olarak bilinir ve yaygın bir uygulamadır.

İşte bir tur turunun açıklaması :

Bir tür iddiası, bir arayüz değerinin altında yatan somut değere erişim sağlar.

t := i.(T)

Bu ifade, arabirim değerinin i beton tip T'yi tuttuğunu ve temel T değerini t değişkenine atar.

İ bir T tutmazsa, ifade bir panik tetikler.

Bir arabirim değerinin belirli bir türü içerip içermediğini sınamak için, bir tür iddiası iki değer döndürebilir: temel alınan değer ve iddianın başarılı olup olmadığını bildiren bir boole değeri.

t, ok := i.(T)

İ bir T tutarsa, o zaman t temel değer olacaktır ve tamam doğru olacaktır.

Değilse, ok yanlış olur ve t T tipinin sıfır değeri olur ve panik olmaz.

NOT: değer iarayüz tipi olmalıdır .

tuzaklar

iBir arabirim türü olsa bile , arabirim türü []ideğildir. Sonuç olarak, []ideğer türüne dönüştürmek için bunu ayrı ayrı yapmalıyız:

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

Verim

Performansa gelince, bu yığın akışı yanıtında gösterildiği gibi gerçek değere doğrudan erişimden daha yavaş olabilir .


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

21
Bu cevabın mevcut sorunu düzeltmede
OP'ye

3

@ Ρяσѕρєя tarafından istendiği gibi, bir açıklama https://golang.org/pkg/fmt/#Sprint adresinde bulunabilir . İlgili açıklamaları https://stackoverflow.com/a/44027953/12817546 adresinde ve https://stackoverflow.com/a/42302709/12817546 adresinde bulabilirsiniz . İşte @ Yuanbo'nun cevabı tam olarak.

package main

import "fmt"

func main() {
    var data interface{} = 2
    str := fmt.Sprint(data)
    fmt.Println(str)
}

1
Sanırım her iki yanıtı da @ Yuanbo'nun düzenlenmesi ile birleştirebilirsiniz - ikiniz de kredilendirilecek ve ilgili 'yararlılık' puanınızı toplayacaksınız 😉
Gwyneth Llewelyn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.