首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何知道是否定义了球拍变量

如何知道是否定义了球拍变量
EN

Stack Overflow用户
提问于 2013-11-19 16:30:04
回答 2查看 3.3K关注 0票数 12

如果一个变量是用球拍语言定义的或者没有定义的话,你怎么会有不同的行为呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-20 04:01:17

有几种方法可以做到这一点。但我怀疑这些都不是您想要的,所以我只提供函数的指针(并解释每个函数的问题):

  1. namespace-variable-value是从某个命名空间检索toplevel变量值的函数。不过,这只对REPL交互和REPL代码有用,因为模块中定义的代码无论如何都不会使用这些东西。换句话说,您可以使用这个函数(和相应的namespace-set-variable-value!)来获取值(如果有的话)并设置它们,但是这些值的唯一使用是在模块中本身并不存在的代码中。换句话说,使用这个工具就像保留一个将符号映射到值的哈希表一样好,只是在REPL上稍微方便一些,因为您只需键入名称.
  2. 更有可能的是,这类事情是在宏中完成的。第一种方法是使用特殊的#%top宏。此宏将自动插入模块中未被绑定的所有名称。这个宏通常做的事情是抛出一个错误,但是您可以在代码中重新定义它(或者用您自己的语言重新定义它),用这些未知的名称来做其他事情。
  3. 一种稍微复杂一些的方法是使用identifier-binding函数--再次,在宏中,而不是在运行时--并使用它获取有关宏的某个名称的信息,并根据该名称决定扩展到什么。

最后两个选项更有用,但它们不是新手级的宏,这就是为什么我怀疑你问错了问题。为了澄清,您可以使用它们编写一种defined?特殊表单,它检查是否定义了某个名称,但这个问题将由宏根据其余代码回答,因此询问它并不真正有用。如果您希望能够在其他动态语言中启用使用此类谓词的代码,那么最好的方法是重新定义#%top,以执行某种查找(哈希表或全局命名空间),而不是抛出编译错误--但是,与显式使用哈希表之间的区别主要是修饰性的(再说一次,这不是一件新手的事情)。

票数 12
EN

Stack Overflow用户

发布于 2013-11-23 10:55:50

首先,读伊莱的答案。然后,根据Eli的答案,您可以这样实现defined?宏:

代码语言:javascript
运行
复制
#lang racket

; The macro
(define-syntax (defined? stx)
  (syntax-case stx ()
    [(_ id)
     (with-syntax ([v (identifier-binding #'id)])
       #''v)]))

; Tests
(define x 3)
(if (defined? x) 'defined 'not-defined) ; -> defined

(let ([y 4])
   (if (defined? y) 'defined 'not-defined)) ; -> defined

(if (defined? z) 'defined 'not-defined) ; -> not-defined

它适用于这种基本情况,但它有一个问题:如果z未定义,则认为已定义并使用其值的if分支将引发编译时错误,因为普通if在运行时(动态)检查其条件值:

代码语言:javascript
运行
复制
; This doesn't work because z in `(list z)' is undefined:
(if (defined? z) (list z) 'not-defined) 

因此,您可能需要的是一个if-defined宏,它在编译时(而不是在运行时)告诉if的哪个分支:

代码语言:javascript
运行
复制
#lang racket

; The macro
(define-syntax (if-defined stx)
  (syntax-case stx ()
    [(_ id iftrue iffalse)
     (let ([where (identifier-binding #'id)])
       (if where #'iftrue #'iffalse))]))

; Tests
(if-defined z (list z) 'not-defined) ; -> not-defined

(if-defined t (void) (define t 5))
t ; -> 5

(define x 3)
(if-defined x (void) (define x 6))
x ; -> 3
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20076868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档