我应该能够键入断言一串字符串映射吗?

时间:2015-09-11 19:37:09

标签: go

我正在使用Go NSQ library收到一条消息,其中字段是loadSQB: function (jsonstr) { jsonstr=JSON.stringify(jsonstr); //Solution for the Question var $tt = this[0]; $('.sqlcolumn').remove(); $('.sqlwhere').remove(); $('.sqlgroup').remove(); $('.sqlsort').remove(); var j=eval('(' + jsonstr + ')'); //Got Error in this line var coldiv =$(".addnewsqlcolumn"); var sortdiv =$('.addnewsqlsort'); var groupdiv=$('.addnewsqlgroup'); var wherediv=$('.addnewsqlwhere'); /*rebuild col data*/ for(var i=0;i<j.columndata.length;i++){ //j.columndata[i].columnslot, j.columndata[i].columnvalue coldiv[0].opts.onselect(j.columndata[i].columnslot,coldiv,{columnas:j.columndata[i].columnas}); } /*rebuild sort data*/ for(var i=0;i<j.sortdata.length;i++){ //j.sortdata[i].columnslot, j.sortdata[i].columnas sortdiv[0].opts.onselect(j.sortdata[i].columnslot,sortdiv,{columnas:j.sortdata[i].columnas}); } /*rebuild group by data*/ for(var i=0;i<j.groupdata.length;i++){ //j.groupdata[i].columnslot, groupdiv[0].opts.onselect(j.groupdata[i].columnslot,groupdiv,null); } /*rebuild where data*/ for(var i=0;i<j.wheredata.length;i++){ //j.wheredata[i].columnslot, j.wheredata[i].opslot,j.wheredata[i].chainslot,j.wheredata[i].columnvalue wherediv[0].opts.onselect(j.wheredata[i].columnslot,wherediv,{columnslot:j.wheredata[i].columnslot,opslot:j.wheredata[i].opslot,chainslot:j.wheredata[i].chainslot,columnvalue:j.wheredata[i].columnvalue}); } } 的一部分。我觉得我应该能够键入断言这个字段为map[string]string,但它失败了,我无法判断这是否是预期的。

此代码段会复制行为https://play.golang.org/p/qcZM880Nal

为什么这种类型的断言会失败?

2 个答案:

答案 0 :(得分:2)

简要介绍here in the FAQ

类型[]interface{}[]map[string]string在内存中有两种不同的表示形式。它们之间没有直接的转换方式。

此外,即使允许转换,您也应该注意到根本无法成功断言到其他基本类型(http://play.golang.org/p/zMp1qebIZZ)。您只能断言原始类型或其他类型的接口

// panics
var i interface{} = int32(42)
_ = i.(int64)

答案 1 :(得分:1)

所提到的转换不符合Jim的回答所述。但是,如果您实际拥有所声明的类型,并且您声明它实现的接口只是interface{},则类型断言可以正常工作。我不想推测为什么另一个不起作用的细节,但我相信这是因为你必须分两个阶段拆箱,因为切片内的map[string]string实际上被视为一些interface{}自己。这是一个例子;

package main

import "fmt"

func main() {
    var value interface{}

    value = []map[string]string{{"address": string("this is interface literal")}}
    // value = []map[string]string{{"address": "this is map literal"}}

    AssertIt(value)


}

func AssertIt(value interface{}) {
    if str, ok := value.([]map[string]string); ok && len(str) > 0 {
        fmt.Println(str[0]["address"])
    } else {
        fmt.Println("nope")
    }
}

https://play.golang.org/p/hJfoh_havC