在Racket中,我希望能够窥视端口中的任何位置(也在当前位置之前),并在那里读取内容,而不会以任何方式影响端口。指定的位置(以下代码中的start-pos
)应该是从头开始,而不是相对于当前端口位置!
我的第一次尝试:
(define (extract-string port start-pos span)
(define pos (file-position port))
(file-position port start-pos)
(define result (read-string span port))
(file-position port pos)
result)
(define port (open-input-string "Hello world"))
(port-count-lines! port)
(port-next-location port)
(extract-string port 0 3)
(port-next-location port)
输出:
1
0
1
"Hel"
1
3
4
以某种方式,(file-position port pos)
...
我的第二次尝试:
(define (extract-string port start-pos span)
(define port2 (peeking-input-port port #:init-position start-pos))
(read-string span port2))
(define port (open-input-string "Hello world"))
(port-count-lines! port)
; port-next-location is not affected; great
(port-next-location port)
(extract-string port 1 3)
(port-next-location port)
; Reading from an earlier point does not work!
(read-string 6 port)
(extract-string port 1 3)
(read-string 5 port)
输出:
1
0
1
"Hel"
1
0
1
"Hello "
"wor"
"world"
编辑:预期输出:
1
0
1
"Hel"
1
0
1
"Hello "
"Hel"
"world"
一个小的改进,但它仍然没有按预期工作..出于某种原因,port2
的初始位置偏离port
的初始位置,尽管参考文献
结果端口的初始位置(由文件位置报告) 是( - 初始位置1),无论是否位于。
在Racket中不可能这样做吗?
答案 0 :(得分:1)
评论后修改:
(define port (open-input-string "Hello world"))
(define (extract-string-getter my_port)
(let* ((prev_pos (file-position my_port))
(new_port (open-input-string (port->string my_port))))
(file-position my_port prev_pos)
(lambda (start_pos span)
(peek-string span start_pos new_port))
))
(define runner (extract-string-getter port))
runner
(runner 1 3)
(runner 1 3)
;(runner 5 9)
(port-count-lines! port)
; port-next-location is not affected; great
(port-next-location port)
;(extract-string port 1 3)
(port-next-location port)
; Reading from an earlier point does not work!
(read-string 6 port)
(runner 0 2)
(read-string 5 port)
(runner 6 9)
您仍然存在范围问题:)了解范围内外非常重要。
内部lambda有一个状态,通过保存对它的引用,'reader',我能够重用它的内部对象的状态!
<强>输出:强>
#<procedure:...\Documents\1.rkt:18:4>
"ell"
"ell"
1
0
1
1
0
1
"Hello "
"He"
"world"
"world"
重要事项: