为了账号安全,请及时绑定邮箱和手机立即绑定

检索任意地图变量的键

检索任意地图变量的键

Go
潇湘沐 2023-03-21 17:01:22
我想获取任意地图变量的键。我发现了这个函数,它复制了 PHParray_keys行为:https://www.php2golang.com/method/function.array-keys.html。但是下面的代码:items := map[string]int{    "one":   1,    "two":   2,    "three": 3,}keys := ArrayKeys(items)抛出下一个“编译时”异常:不能在 ArrayKeys 的参数中使用项目(类型 map[string]int)作为类型 map[interface {}]interface {}我究竟做错了什么?这是一个例子: https: //play.golang.org/p/0ImqjPJFFiE
查看完整描述

3 回答

?
慕森王

TA贡献1777条经验 获得超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 的工作方式。


查看完整回答
反对 回复 2023-03-21
?
MMTTMM

TA贡献1869条经验 获得超4个赞

在 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"]


查看完整回答
反对 回复 2023-03-21
?
aluckdog

TA贡献1847条经验 获得超7个赞

错误中明确提到:


不能在 ArrayKeys 的参数中使用项目(类型 map[string]int)作为类型 map[interface {}]interface {}


由于类型不匹配,您会遇到上述错误。如果你想在函数中使用任何类型,你可以选择接口,因为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上的工作代码



查看完整回答
反对 回复 2023-03-21
  • 3 回答
  • 0 关注
  • 94 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信