1

mongodb ( mgo )から取得したデータを処理しようとしています。

残念ながら、文字列のリストの正しい型をアサートできません。私が取り組んでいる機能は次のとおりです。

func generate_version_histogram(userStats []interface{}) map[string]int {
    var histogram map[string]int
    for _, _u := range userStats {
        u := _u.(bson.M)
        for _, version := range (u["v"]).([]string) {
            if _, alreadyhere := histogram[version]; alreadyhere {
                histogram[version] += 1
            } else {
                histogram[version] = 1
            }
        }
    }
    return histogram
}

残念ながら、次の実行時パニックが発生しています。

interface conversion: interface is []interface {}, not []string

なぜこれが起こっているのかについて何か考えはありますか?これらの文字列を取得するにはどうすればよいですか?

4

2 に答える 2

10

これは Go でよくある間違いです。

その理由は次のとおりです。Go[]interface{}ではインターフェイスではなく、要素がそれぞれのinterface{}型であるスライス型です。

各要素はorinterface{}ではなく であるため、より多くのメモリが各要素によって占有されます (基になる型と含まれる値を格納する必要があります)。したがって、値をor値に直接変換することはできません。intFoointerface{}[]interface[]string[]T

では、どのように に変換[]interface{}します[]stringか?

解決策は非常に単純です。各要素を変換します。

package main

import "fmt"

func main() {
    foo := []interface{}{"a", "b", "c"}

    // we want to convert foo to a []string
    out := []string{}

    for _, v := range foo {
        // using a type assertion, convert v to a string
        out = append(out, v.(string))
    }

    fmt.Println(out)
}

ここで実行可能な例

于 2014-05-10T14:14:14.447 に答える
4

A[]interface{}は になることはありません[]string。スライスにはバッキング配列があり、それらの要素は特定のサイズでなければなりません。これは、実装の詳細に応じて正確に正しい場合と正しくない場合がありますが、 の各要素には[]interface{}が含まれますinterface{}。これらすべてinterface{}が「実際の」文字列である場合、それらは文字列自体ではなく、文字列のラッパーまたはそれへのポインターになります。したがって、自分自身の個々の要素を変換する必要があり[]interface{}ます。

stringSlice := make([]string, len(u["v"]))
for i,raw := range u["v"] {
    str,ok := raw.(string)
    if !ok {
        // Something is wrong, not a string like we expected
    }
    stringSlice[i] = str
}
于 2014-05-10T14:10:17.130 に答える