- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用来自 this accepted answer 的方案实现在 Racket LISP 中为个人学习项目实现协程。 .但是,当将我的 .rkt 文件加载到 Racket repl 时,出现以下错误:
; 3.rkt:111:18: define: not allowed in an expression context
; in: (define (run-handler) (make-generator (lambda (yield) (send
; (get-dp-data-object key) run))))
它似乎在提示这部分代码中的定义:
108 (define-syntax (define-coroutine stx)
109 (syntax-case stx ()
110 ((_ (name . args) . body )
111 #`(define (name . args)
112 (make-generator
113 (lambda (#,(datum->syntax stx 'yield))
114 . body))))))
根据accepted answer here这个确切的错误不被 Scheme 共享,并且在尝试在表达式中定义时是 Racket 独有的。
代码调用(define-coroutine)似乎是:
518 ;; Qt-esque connect macro
519 (define-syntax connect-message
520 (syntax-rules ()
521 [(register src-obj-key msg-type dst-obj-key handler)
522 (register-message-handler
523 msg-type
524 (begin
525 (define-coroutine
526 (handler-accessor)
527 (if (eqv? (get-dp-data-object dst-obj-key) #f)
528 #f
529 (send
530 (get-dp-data-object dst-obj-key)
531 handler
532 (get-field args msg))))
533 handler-accessor))]))
这是我的第一个 Racket 项目,所以我正在学习很多。上面的 (begin) 试图定义并返回一个调用对象方法的协程。我确信这个代码片段有很多问题,但是调试器用上面的问题阻止了我,阻止我得到以后的错误:)
我在 Racket、Scheme 或 LISP 方面几乎不够熟练,无法解决这个问题,目前我很难理解这个错误。有人可以为我解决这个问题并希望纠正这个问题,这样我就可以让这个协程代码在 Racket 中工作吗?
最佳答案
在 Racket 中,begin
不会创建新范围。1 这意味着您在 begin
中定义的任何内容表单仍在该表单之外的范围内。这也意味着 begin 不会改变上下文,所以如果你在表达式上下文中,begin
保留那个。
define
表单具有(大致)以下语法:
(define <id> <expr>)
在哪里<id>
是变量名,<expr>
是一个表达式。然而,define
表单本身不是一个表达式,所以这样的东西是无效的:
(define x (define y 5))
因为 begin 不改变上下文,所以这也是无效的:
(define x
(begin
(define y 5)
y))
相反,您可以使用 let
创建一个新的范围。而且因为let本身就是一个表达式,所以可以放在define中。所以你可以这样写:
(define x
(let ()
(define y 5)
y))
现在,x
绑定(bind)到 5
正如预期的那样。
回到你原来的问题,你有代码:
518 ;; Qt-esque connect macro
519 (define-syntax connect-message
520 (syntax-rules ()
521 [(register src-obj-key msg-type dst-obj-key handler)
522 (register-message-handler
523 msg-type
524 (begin
525 (define-coroutine
526 (handler-accessor)
527 (if (eqv? (get-dp-data-object dst-obj-key) #f)
528 #f
529 (send
530 (get-dp-data-object dst-obj-key)
531 handler
532 (get-field args msg))))
533 handler-accessor))]))
我假设 register-message-handler
是一个函数,因此需要一个表达式。但是你有 define-coroutine
,谁的阐述是define
形式。所以而不是使用 begin
, 你可以使用 let
把它变成一个表达式,给你这样的东西:
(register-message-handler
msg-type
(let ()
(define-coroutine (handler-accessor) ....)
handler-accessor))
1糟糕的设计决定……我知道。几十年前桥下的水。 :(
关于scheme - 如何修复此 Scheme 协程代码以在 Racket 中运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51690804/
在我的设置中,我试图有一个界面 Table继承自 Map (因为它主要用作 map 的包装器)。两个类继承自 Table - 本地和全局。全局的将有一个可变的映射,而本地的将有一个只有本地条目的映射。
Rust Nomicon 有 an entire section on variance除了关于 Box 的这一小节,我或多或少地理解了这一点和 Vec在 T 上(共同)变体. Box and Vec
我是一名优秀的程序员,十分优秀!