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

在 Go 中使用 c 样式迭代器的惯用方法

在 Go 中使用 c 样式迭代器的惯用方法

Go
慕村9548890 2021-11-08 18:26:59
我是 Go 编程的新手(3-4 天),我正在尝试编写一些代码,使用 cgo 使用现有的第三方 C 库读取二进制文件。C 库执行此操作的方式似乎相当标准(对于 C)。稍微简化一下,它看起来像:int main(int argc, char *argv[]) {    file_t *file = file_open(filename);    index_t *index = index_load(file, filename);    iterator_t *iter = query(idx, header, region);    record_t *record = record_init();    while (iterator_next(file, iter, record) >= 0) {        /* Do stuff with record */    }    iterator_destroy(iter);    record_destroy(record);    file_close(file);    return 0;}我编写了以下 Go 代码:func main() {    file := Open(filename)    record := NewRecord()    iter := file.Query(region)    for {        n, err := file.Next(iter, record)        if err != nil {            log.Fatal(err)        }        if n <= 0 {            // No more records to read.            break        }    }}这是有效的,因为它将允许我访问特定查询区域中的记录。我的问题是,这是否是在 Go 中处理此任务的惯用方法,还是有更好的选择?我见过诸如http://ewencp.org/blog/golang-iterators 之类的网站,但似乎无法让这些示例与 C 库一起使用(我认为这可能是因为 C 库正在重用 record_t 变量在每次迭代中,而不是创建一个新变量,但也许这只是我对 Go 缺乏经验)。
查看完整描述

1 回答

?
慕哥6287543

TA贡献1831条经验 获得超10个赞

您所做的与在带有 的文件中移动没有什么不同io.Reader:


err, n := error(nil), 0

for err == nil {

    err, n = f.Read(in)

    // ...do stuff with in[:n]...

}

或使用(*bufio.Scanner).Scan()(参见文档):


for scanner.Scan() {

    // ...do something with scanner.Text()...

}

if err := scanner.Err(); err != nil {

    log.Fatalln(err)

}

我认为您很少想要链接到的博客文章中更奇特的迭代器选项,那些带有闭包或通道的选项。通道尤其会调用许多用于协调实际线程工作负载的机制,并且就约定而言,Go for 循环中的典型情况取决于它们正在迭代的内容而略有不同。(在这方面,它就像 C 中的迭代,但不同于(比如说)Python、C++ 或 Java。)


查看完整回答
反对 回复 2021-11-08
  • 1 回答
  • 0 关注
  • 166 浏览
慕课专栏
更多

添加回答

举报

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