读取文件 - '(#<void> ... #<void>) 从何而来?



以下代码用于逐行显示读取的文本:

#!/usr/bin/env racket
#lang racket/base
(require racket/string)
(require racket/file)

(require racket/file)
(display "Line by line with for loop:nn")
(define f "../file-to-be-read.short")
(define content (file->lines f))
(for ([l content]) (display l))

(define (do-sth-to-each-line fn-name) 
(define f "../file-to-be-read.short")
(define content (file->lines f))
(map fn-name content))
(display "nnAnd now line by line with map and display:nn")
(do-sth-to-each-line display)

代码从../file-to-be-read.short读取,其内容为:

Not that I think you did not love your father,
But that I know love is begun by time,
And that I see, in passages of proof,
Time qualifies the spark and fire of it.

调用(do-sth-to-each-line display)的结果如下:

Not that I think you did not love your father,But that I know love is begun by time,And that I see, in passages of proof,Time qualifies the spark and fire of it.'(#<void> #<void> #<void> #<void> #<void> #<void> #<void>)

'(#<void> #<void> #<void> #<void> #<void> #<void> #<void>)来自哪里?为什么(for ([l content]) (display l))不产生我意想不到的输出?

#<void>display函数的返回值,因此'(#<void> #<void> #<void> #<void> #<void> #<void> #<void>)mapdisplay相对于content的结果(mapfor都生成结果列表,因此for返回相同的结果)。

如果您想为列表中的每个元素运行一些副作用,您应该使用for-each

此外,不要在define中使用define,使用let引入局部变量,并考虑使用displayln:

#lang racket
(require racket/string)
(require racket/file)
(define (print-file filename) 
(for-each displayln
(file->lines filename)))
(displayln "Now line by line with for-each and displayln:")
(print-file "../file-to-be-read.short")

使用for的更好方法是:

(define (display-file filename)
(call-with-input-file filename
(lambda (port) (for ([line (in-lines port)]) (display line)))))

in-lines返回一个序列,该序列一次迭代从端口读取的行,而不是先将整个文件读取到列表中,这使得它在大型输入文件上使用的内存要少得多。

还有display-lines作为for-each的替代品(正如Martin所指出的,它比这里的map更好),尽管它也需要首先读取整个输入文件:

(display-lines (file->lines filename) #:separator #u200C)

它只显示给定列表中的每个元素,中间有一个分隔符(默认为#newline,使其行为类似于每个元素的displayln,而不是display)。在这种情况下,为了模仿其他版本的行为,即不在行之间插入任何内容,U+200C ZERO WIDTH NON JOINER被用作分隔符,以在支持Unicode的程序中查看输出时获得相同的视觉效果。#space是另一个选项,因为ZWNJ可能会对非ASCII文本造成意外影响(As可以而不是在行之间有分隔符)。

相关内容

  • 没有找到相关文章

最新更新