golang:读取文件生成器

Pie*_*gen 1 python generator go

我正在学习围棋的语言,并试图重写一些使用golang我的Python代码.我写了一个生成器函数,它逐行读取文本文件并发送(使用yield关键字)只有"有效"行(忽略空白行,重新构造未完成的行).

示例文件(myfile.txt):

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

#126= BARBAZ('poeazpfodsp',
234,56);
Run Code Online (Sandbox Code Playgroud)

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) 
Run Code Online (Sandbox Code Playgroud)

显示:

#123= FOOBAR(1.,'text');
#126= BARBAZ('poeazpfodsp',234,56);    
Run Code Online (Sandbox Code Playgroud)

现在,我尝试使用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)
    }
}
Run Code Online (Sandbox Code Playgroud)

显示:

#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');
...
Run Code Online (Sandbox Code Playgroud)

在golang中这样做的正确方法是什么?

小智 6

在Go中你可以使用渠道而不是收益,这非常方便.

包主

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

func ValidLines(filename string) (c chan string) {
    c = make(chan string)
    buff := ""
    go func() {
        file, err := os.Open(filename)
        if err != nil {
            close(c)
            return
        }

        reader := bufio.NewReader(file)
        for {
            line, err := reader.ReadString('\n')
            if err != nil {
                close(c)
                return
            }
            line = strings.TrimSpace(line)
            if line == "" {
                continue
            }
            buff += line
            if line[len(line)-1] != ';' {
                continue
            }
            c <- buff
            buff = ""
        }
    }()
    return c
}

func main() {
    for line := range ValidLines("myfile.txt") {
        fmt.Println(line)
    }
}
Run Code Online (Sandbox Code Playgroud)