Racket语言如何避免循环定义,解决标识符未定义引用报错
问题解决办法
你提到的两种思路都可以完美解决该问题,核心错误原因有两个:
- 构造
text%实例时直接引用还未完成绑定的text变量,触发前向引用报错 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
相关产品推荐
相关产品推荐

