我想获取任意映射变量的键。我发现了该函数,该函数复制了PHP array_keys
行为:https://www.php2golang.com/method/function.array-keys.html。但是下面的代码:
items := map[string]int{
"one": 1,
"two": 2,
"three": 3,
}
keys := ArrayKeys(items)
引发下一个“编译时”异常:
不能将项目(类型map [string] int)用作类型map [interface {}]接口{}指向ArrayKeys
我在做什么错了?
答案 0 :(得分:3)
您应该更改功能以适合您的类型:
func ArrayKeys(elements map[string]int) []string {
i, keys := 0, make([]string, len(elements))
for key, _ := range elements {
keys[i] = key
i++
}
return keys
}
https://play.golang.org/p/n5kZego0ePY
但是为什么要更改签名?
如果Go中的函数采用空接口,则所有包含的变量都不再具有类型。但是Go是强类型的,因此处理没有类型的变量很困难。如果您提供像您这样的函数,那么代码应该真正处理任何类型。为此,您将需要使用反射包。如果发生错误而错过了某些内容,则程序将发生错误。编写服务器时,它可以运行几个月,然后停止运行。
如果您为每种类型编写一个ArrayKey
函数,那么情况就会有所不同。编译器可确保您的代码健壮且不会在那一刻发生恐慌。如果您想尝试将该函数与其他类型的地图一起使用,则代码将无法编译。 Go就是这样工作的。
答案 1 :(得分:2)
在Go中,编写一个简单的函数。例如,
package main
import "fmt"
func main() {
items := map[string]int{
"one": 1,
"two": 2,
"three": 3,
}
keys := func(m map[string]int) []string {
mk := make([]string, 0, len(m))
for k := range m {
mk = append(mk, k)
}
return mk
}(items)
fmt.Printf("%d %q\n", len(keys), keys)
}
游乐场:https://play.golang.org/p/B0kOxAGbQCZ
输出:
3 ["three" "one" "two"]
对于已排序的键,
package main
import (
"fmt"
"sort"
)
func main() {
items := map[string]int{
"one": 1,
"two": 2,
"three": 3,
}
keys := func(m map[string]int) []string {
mk := make([]string, 0, len(m))
for k := range m {
mk = append(mk, k)
}
sort.Strings(mk)
return mk
}(items)
fmt.Printf("%d %q\n", len(keys), keys)
}
游乐场:https://play.golang.org/p/IQLx7gjGk8j
输出:
3 ["one" "three" "two"]
答案 2 :(得分:0)
明确提到的错误:
不能将项目(类型map [string] int)用作类型map [interface {}]接口{}指向ArrayKeys
由于类型不匹配,您遇到了错误。如果要在函数中使用任何类型,则可以使用接口,因为interface{}
不等于map[interface{}]interface{}
如果您确实想使用接口,则可以使用interface{}
来包装来自maps
的数据。否则,您应该使用与上述答案中提到的函数相同的类型作为参数。
package main
import (
"fmt"
)
func ArrayKeys(elements interface{}) []interface{} {
i, keys := 0, make([]interface{}, len(elements.(interface{}).(map[string]int)))
for key, _ := range elements.(interface{}).(map[string]int) {
keys[i] = key
i++
}
return keys
}
func main() {
items := map[string]int{
"one": 1,
"two": 2,
"three": 3,
}
keys := ArrayKeys(items)
fmt.Println(keys)
}
在Go Playground上工作的代码