You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Racket语言如何避免循环定义,解决标识符未定义引用报错

问题解决办法

你提到的两种思路都可以完美解决该问题,核心错误原因有两个:

  1. 构造text%实例时直接引用还未完成绑定的text变量,触发前向引用报错
  2. callback参数要求传入触发时执行的过程,不能直接写执行语句,否则会在实例创建时就立即求值,不会等到文本修改时触发

方案1:实例创建完成后再分配callback

text%类内置set-callback方法,你可以先创建无callback的实例,完成绑定后再手动设置回调,不会触发前向引用报错:

#lang racket/gui

(define toplevel (new frame% [label "MD View"] [width 800] [height 300]))

(define canvas (new editor-canvas% [parent toplevel] [style '(no-hscroll)]))
(define canvas2 (new editor-canvas% [parent toplevel] [style '(no-hscroll)]))

(define text2 (new text%))
;; 先创建无回调的text实例
(define text (new text%))
;; 实例绑定完成后再设置回调
(send text set-callback (lambda (t event)
                          ;; 先清空text2原有内容,再同步最新文本
                          (send text2 erase)
                          (send text2 insert (send t get-text))))

(send canvas set-editor text)
(send canvas2 set-editor text2)

(send text auto-wrap #t)
(send text set-padding 10 10 10 10)

(send text2 auto-wrap #t)
(send text2 set-padding 10 10 10 10)

(new button% [parent toplevel]
             [label "write"]
             [callback (lambda (button event)
                         (send text2 insert "written"))])

(new button% [parent toplevel]
             [label "copy"]
             [callback (lambda (button event)
                         (send text2 insert (send text get-text)))])

(send toplevel show #t)

方案2:利用回调参数规避前向引用

text%的回调过程默认会接收两个入参:第一个就是当前触发回调的text%实例本身,第二个是事件对象。你完全不需要引用外部的text变量,直接用回调的第一个入参即可,从根源上避免循环/前向引用:

#lang racket/gui

(define toplevel (new frame% [label "MD View"] [width 800] [height 300]))

(define canvas (new editor-canvas% [parent toplevel] [style '(no-hscroll)]))
(define canvas2 (new editor-canvas% [parent toplevel] [style '(no-hscroll)]))

(define text2 (new text%))
(define text (new text%
                  ;; 直接用回调第一个入参指代当前text实例,不需要引用外部text变量
                  [callback (lambda (t event)
                              (send text2 erase)
                              (send text2 insert (send t get-text)))]))

(send canvas set-editor text)
(send canvas2 set-editor text2)

(send text auto-wrap #t)
(send text set-padding 10 10 10 10)

(send text2 auto-wrap #t)
(send text2 set-padding 10 10 10 10)

(new button% [parent toplevel]
             [label "write"]
             [callback (lambda (button event)
                         (send text2 insert "written"))])

(new button% [parent toplevel]
             [label "copy"]
             [callback (lambda (button event)
                         (send text2 insert (send text get-text)))])

(send toplevel show #t)

两种方案都可以实现text修改后自动同步内容到text2的需求,优先推荐方案2,写法更简洁。


内容的提问来源于stack exchange,提问作者binarysound

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 10:06:05