英文:
Println prints square brackets but interface is not a slice
问题
我遇到了一个奇怪的接口问题,当我尝试打印一个值时,Println会添加方括号。我认为这是因为该接口包含切片,但我不确定应该如何迭代它们。
我很确定这是一个新手问题,但我花了很多时间寻找线索,却找不到任何线索。
此外,我无法在不使用goes的情况下重现它,所以这里是我实际使用的代码:
package main
import "fmt"
import "github.com/belogik/goes"
import "net/url"
func getConnection() (conn *goes.Connection) {
conn = goes.NewConnection("localhost", "9200")
return
}
func main() {
conn := getConnection()
var query = map[string]interface{}{
"query": map[string]interface{}{
"bool": map[string]interface{}{
"must": map[string]interface{}{
"match_all": map[string]interface{}{},
},
},
},
"from": 0,
"size": 3,
"fields": []string{"name"},
}
extraArgs := make(url.Values)
searchResults, err := conn.Search(query, []string{"myindex"}, []string{"mytype"}, extraArgs)
if err != nil {
panic(err)
}
result := searchResults.Hits.Hits
for _, element := range result {
name := element.Fields["name"]
fmt.Println(name)
fmt.Printf("%#v\n", name)
}
}
这将输出:
[One]
[]interface {}{"One"}
[Two]
[]interface {}{"Two"}
[Three]
[]interface {}{"Three"}
然而,如果我尝试像这样循环遍历"name":
for _, e := range name {
fmt.Println(e)
}
我会得到"cannot range over name (type interface {})"的错误提示。
英文:
I'm having a strange problem with interfaces, when I try to print a value Println adds square brackets. I believe this is because that interface contains slices, but I'm not sure how should iterate them.
I'm quite sure it's a newbie question but I spend alot time searching for a clue and can't find any.
Also I couldn't reproduce it without using goes, so here's the code that I actually used:
package main
import "fmt"
import "github.com/belogik/goes"
import "net/url"
func getConnection() (conn *goes.Connection) {
conn = goes.NewConnection("localhost", "9200")
return
}
func main() {
conn := getConnection()
var query = map[string]interface{}{
"query": map[string]interface{}{
"bool": map[string]interface{}{
"must": map[string]interface{}{
"match_all": map[string]interface{}{},
},
},
},
"from": 0,
"size": 3,
"fields": []string{"name"},
}
extraArgs := make(url.Values)
searchResults, err := conn.Search(query, []string{"myindex"}, []string{"mytype"}, extraArgs)
if err != nil {
panic(err)
}
result := searchResults.Hits.Hits
for _,element := range result {
name := element.Fields["name"]
fmt.Println( name )
fmt.Printf( "%#v\n", name )
}
}
This outputs:
[One]
[]interface {}{"One"}
[Two]
[]interface {}{"Two"}
[Three]
[]interface {}{"Three"}
However if I try to loop over the "name" like so:
for _, e := range name {
fmt.Println( e )
}
I'm getting "cannot range over name (type interface {})"
答案1
得分: 1
使用类型断言。例如,
package main
import "fmt"
func main() {
m := map[string]interface{}{}
m["name"] = []interface{}{"One"}
fmt.Println(m)
name := m["name"]
fmt.Println(name)
fmt.Printf("%#v\n", name)
for _, e := range name.([]interface{}) {
fmt.Println(e)
}
}
输出结果:
map[name:[One]]
[One]
[]interface {}{"One"}
One
对于一个接口类型的表达式 x 和一个类型 T,主表达式
x.(T)
断言 x 不是 nil,并且 x 中存储的值的类型是 T。x.(T) 的表示法称为类型断言。
英文:
Use a type assertion. For example,
package main
import "fmt"
func main() {
m := map[string]interface{}{}
m["name"] = []interface{}{"One"}
fmt.Println(m)
name := m["name"]
fmt.Println(name)
fmt.Printf("%#v\n", name)
for _, e := range name.([]interface{}) {
fmt.Println(e)
}
}
Output:
map[name:[One]]
[One]
[]interface {}{"One"}
One
> The Go Programming Language Specification
>
> Type assertions
>
> For an expression x of interface type and a type T, the primary
> expression
>
> x.(T)
>
> asserts that x is not nil and that the value stored in x is of type T.
> The notation x.(T) is called a type assertion.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论