我正在尝试在Racket中使用自定义端口或管道。我想写一个消息到管道,管道检查消息,并根据消息,它返回另一个消息或某个值。
我尝试过这样的事情:
(define (write-s msg)
(let-values ([(in-port transmitting) (make-pipe)]
[(receiving out-port) (make-pipe)])
(write msg out-port)
(let ((message (read receiving)))
(if (equal? message '(DOGE))
(write '(SO AMAZE) transmitting)
'do-nothing)
(if (equal? message '(MUCH PIPES))
(write '(WOW RACKET) transmitting)
'do-nothing))
(read in-port)))
答案 0 :(得分:2)
我建议定义一个简单的辅助函数make-codec-input-port
,它允许您从原始输入端口和“编解码器”功能创建输入端口。这里的关键点 - 我在make-pipe
的Racket文档中对我来说并不明显 - 是你要运行一个调用编解码器函数的thread
。
在这里,我展示了一个简单的编解码器,用#\a
替换每个#\b
个字符。您可以更改其match
语句以执行更有趣的操作。
#lang racket
;; Given an input-port and a codec function, return a new input-port
;; that is the encoded version. `codec` is (input-port? output-port?
;; -> any). For example can be deflate, inflate, gzip-through-ports,
;; gunzip-through-ports, copy-port (the identity function for this),
;; or your own such function.
(define codec-buffer-size (make-parameter 1024))
(define (make-codec-input-port in codec [name #f])
(define-values (pin pout) (make-pipe (codec-buffer-size) name name))
(thread (lambda ()
(codec in pout)
(close-output-port pout)))
pin)
;; Example of a codec function.
(define (replace-a-with-b in out) ;; (input-port? output-port? -> any)
(let loop ()
(define ch (read-char in))
(unless (eof-object? ch)
(write-char (match ch
[#\a #\b]
[x x])
out)
(loop))))
;; You could also write the codec function a bit more simply using
;; `in-port`:
(define (replace-a-with-b in out) ;; (input-port? output-port? -> any)
(for ([ch (in-port read-char in)])
(write-char (match ch
[#\a #\b]
[x x])
out)))
;; Example direct use of the codec function.
(let ()
(define orig-in (open-input-string "axaxax"))
(replace-a-with-b orig-in (current-output-port)))
;; => bxbxbx
;; Example use of the encoded input port. With this, a user of the
;; port need not know anything about the codec function.
(let ()
(define orig-in (open-input-string "axaxax"))
(define encoded-in (make-codec-input-port orig-in replace-a-with-b))
(port->string encoded-in))
;; => "bxbxbx"