douyu7879 2016-05-26 10:23
浏览 70
已采纳

golang:读取文件生成器

I'm learning go language and try to rewrite some of my Python code using golang. I wrote a generator function that reads a text file line by line and send (using yield keyword) only "valid" lines (blank lines are ignored, uncompleted lines are recomposed).

Sample file (myfile.txt):

#123= FOOBAR(1.,'text');

#126= BARBAZ('poeazpfodsp',
234,56);

parse.py:

#!/usr/bin/python
def validlines(filename):
    with open(filename) as fdin:
        buff = ''
        for line in fdin.readlines():
            line = line.strip()
            if line == '':
                continue
            buff += line
            if line[-1] != ';':
                continue
            yield buff
            buff = ''
        fdin.close()

for line in validlines('myfile.txt'):
    print(line) 

displays:

#123= FOOBAR(1.,'text');
#126= BARBAZ('poeazpfodsp',234,56);    

Now, I try to do it the same way using a closure in golang:

parse.go:

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func validLines(filename string) (func() (string, bool)) {

    file, _ := os.Open(filename)
    scanner := bufio.NewScanner(file)

    return func() (string, bool) {
        buff := ""
        for scanner.Scan() {
            line := scanner.Text()
            line = strings.TrimSpace(line)

            if line == "" {
                continue
            }
            buff += line
            if line[len(line)-1] != ';' {
                continue
            }
            return buff, true
        }

        file.Close()
        return "", false
    }
}

func main() {
    vline := validLines("myfile.txt")
    for line, ok := vline(); ok; {
        fmt.Println(line)
    }
}

displays:

#123= FOOBAR(1.,'text');
#123= FOOBAR(1.,'text');
#123= FOOBAR(1.,'text');
#123= FOOBAR(1.,'text');
#123= FOOBAR(1.,'text');
#123= FOOBAR(1.,'text');
#123= FOOBAR(1.,'text');
...

What's the right way to do it in golang?

  • 写回答

4条回答 默认 最新

  • dongmou1964 2016-05-26 10:40
    关注

    This is the for loop of your main which is the problem. With this syntax, here is what it does:

    1. Initialize line and ok with a first call to vline()
    2. If ok is true, run the loop once
    3. Update something at the end of the block, and go to 2.

    So, your problem is that you never update lineand ok. Here is the correct version:

    for line, ok := vline(); ok; line, ok = vline() { ... }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 关于#python#的问题
  • ¥15 主机可以ping通路由器但是连不上网怎么办
  • ¥15 数据库一张以时间排好序的表中,找出多次相邻的那些行
  • ¥50 关于DynamoRIO处理多线程程序时候的问题
  • ¥15 kubeadm部署k8s出错
  • ¥15 Abaqus打不开cae文件怎么办?
  • ¥20 双系统开机引导中windows系统消失问题?
  • ¥15 小程序准备上线,软件开发公司需要提供哪些资料给甲方
  • ¥15 关于生产日期批次退货退款,库存回退的问题
  • ¥15 手机应用的时间可以修改吗