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

有没有一种惯用的方式来为 golang 切片做“in”

有没有一种惯用的方式来为 golang 切片做“in”

Go
撒科打诨 2021-09-21 16:23:47
我想检查一个值是否在一个值中。实现这一目标的最佳方法是什么?类似于以下内容:if "foo" in []string{"foo", "bar"}...我已经编写了以下代码,但不确定它是多么地道(golang 新手):// Convert a slice or array of a specific type to array of interface{}func ToIntf(s interface{}) []interface{} {    v := reflect.ValueOf(s)    // There is no need to check, we want to panic if it's not slice or array    intf := make([]interface{}, v.Len())    for i := 0; i < v.Len(); i++ {        intf[i] = v.Index(i).Interface()    }    return intf}func In(s []interface{}, val interface{}) bool {    for _, v := range s {        if v == val {            return true        }    }    return false}所以,为了使用这个,这是我写的一个测试方法。func TestIn(t *testing.T) {    s := []string{"foo", "bar", "kuku", "kiki"}    for _, v := range s {        if !In(ToIntf(s), v) {            t.Error("Should be in")        }    }    if In(ToIntf(s), "foobar") {        t.Error("Should not be in")    }}
查看完整描述

2 回答

?
白衣非少年

TA贡献1155条经验 获得超0个赞

在 go 中,对于可以用简单循环表示的函数,以这种方式实现的惯用方式。例如,您的方法可以这样编写:


for _, value := range slice {

    if value == var {

        doSomething()

    }

}

显然,它有点冗长,但前提是您尝试在 go 中进行翻译 language or choice here。


进行反射的缺点是,您会破坏性能,而不会比编写代码以集成到搜索中而不是简单地将其视为一个条件那么简单。


查看完整回答
反对 回复 2021-09-21
?
三国纷争

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

如果您需要一种便宜的方法来检查这个(如果您必须经常检查),我会使用地图进行更便宜的查找。像这样:


type Foo string


var sl []string

var m map[string]int


//insert

sl = append(sl, "bar")

m["bar"] += 1


// delete ,e.g at position i

m[sl[i]] -= 1

sl[len(sl)-1], s[:len(sl)-1]



//test

if count := m["abc"]; count>0 {

 // "abc" in sl 

}

当然,如果您更改切片中的某些内容,两者都会增加开销。那要看你的情况了。


如果您的切片没有改变,并且您将进行大量“in”测试,您可以为此构建一个更简单的地图:


m := make(map[string]struct{}, len(sl))

for _, value := range sl {

    m[value] = struct{}

}


//test 


if _, ok := m["abc"]; ok {

  // "abc" is in sl

}


查看完整回答
反对 回复 2021-09-21
  • 2 回答
  • 0 关注
  • 275 浏览
慕课专栏
更多

添加回答

举报

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