dongxi1879 2015-12-26 14:06
浏览 56
已采纳

通过遍历“转到”列表来查找项目

I'm attempting to port some C to Go.

I'm essentially looking for something in Go akin to Haskell's find :: (a -> Bool) -> [a] -> Maybe a

I have (roughly) this C for finding an item in a "list" by iterating through it:

struct foo {
    struct foo *next;
    char *name;
}

struct foo *foo_list;

// Snip

struct foo *foo = NULL;
for (f = foo_list; f; f = f->next) {
    if (!strcmp("bar", f->name) {
        foo = f;
    }
}

if (foo)
    // Stuff

How can I do this nicely and idiomatically in Go?

The "list" is likely to be small; performance characteristics aren't particularly interesting.

Am I likely to want a slice, or a list? A "list" of Foos or *Foos?

I currently have the following, but I suspect it's not particularly "idiomatic Go"!

var FooTable *list.List

// Snip

var foo *Foo = nil

for e := FooTable.Front(); e != nil; e = e.Next() {
    if e.Value.(*Foo).name == "bar" {
        foo = e.Value.(*Foo)
        break
    }
}
  • 写回答

1条回答 默认 最新

  • douhan9748 2015-12-26 14:20
    关注

    For idiomatic Go you want a slice of pointers to Foo (though if Foo is very small you might choose just a slice of Foo), so

    var foos []*Foo
    

    And then for searching

    var found *Foo
    for _, foo := range foos {
        if foo.name == "bar" {
            found = foo
            break
        }
    }
    
    if found != nil {
        // stuff
    }
    

    If you do this a lot you'll wrap it up with some types something like this

    type Foos []*Foo
    
    func (fs Foos) find(what string) (foo *Foo) {
        for _, foo = range foos {
            if foo.name == what {
                return foo
            }
        }
        return nil
    }
    

    Then you can do

    var foos Foos
    foo := foos.find("bar")
    if foo != nil {
        // something
    }
    

    PS Nice to answer a question for someone I've actually met!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号