2017-09-07 38 views
0

我想編寫一個函數,它讀取文件中的行併發送到通道中進行進一步處理。我是新來的快去這裏是我想出了以下主要是課本上的例子閱讀器功能:如何在一個匿名函數中逐行掃描一個文件並將其傳遞給一個通道

func reader(file string) <-chan string { 
    out := make(chan string) 

    f, err := os.Open(file) 
    if err != nil { 
     log.Fatal(err) 
    } 
    defer f.Close() 

    s := bufio.NewScanner(f) 
    go func() { 
     for s.Scan() { 
      out <- s.Text() 
     } 
     close(out) 
    }() 

    return out 
} 

main()功能我傳遞一個文件指針到閱讀器功能,並嘗試漏出通道如下:

func main() { 
    out := reader(*f) 
    for range out { 
     fmt.Println(<-out) 
    } 
} 

但是,我得不到任何comilation或運行時錯誤,但輸出爲空。如果我不把for循環放到goroutine中,我可以用reader()函數打印文件,而不會出現任何問題。

我還試圖將reader()函數中的掃描器,通道或兩者都傳遞給匿名函數。但它沒有解決問題。任何人都可以解釋爲什麼此代碼不起作用,以及如何補救?

回答

0

您正在關閉文件,然後再閱讀它。

你只打印每隔一行。

將延遲移入實際發生讀取的閉包中。

func reader(file string) <-chan string { 
    out := make(chan string) 

    f, err := os.Open(file) 
    if err != nil { 
     log.Fatal(err) 
    } 

    s := bufio.NewScanner(f) 
    go func() { 
     defer f.Close() 
     defer close(out) 
     for s.Scan() { 
      out <- s.Text() 
     } 
     if err := s.Err(); err != nil { 
      fmt.Println("error reading file:", err) 
     } 
    }() 

    return out 
} 

然後,從範圍子句打印值,內接收到的for循環不是一個第二值​​:

func main() { 
    out := reader(os.Args[1]) 
    for line := range out { 
     fmt.Println(line) 
    } 
} 
相關問題