【问题标题】:Naming variables using variables in Racket?使用 Racket 中的变量命名变量?
【发布时间】:2015-04-04 14:58:24
【问题描述】:

如果我有两个变量,例如

(define x 10)
(define y 20)

我想创建一个新变量,使用 xy 的值来创建名字,我该怎么做?

例如,假设我想创建一个名为 variable-x-y

的新变量
(define variable-x-y "some-value")

在这种情况下,x 为 10,y 为 20。

基本上总结一下,我希望能够输入 variable-10-20 并让它返回 "some-value"

如果这听起来像是一个新手问题,我很抱歉。我对 Racket 很陌生。

编辑: 另外,如果只给出 xy 的值(在程序)?

例如,假设我能够以某种方式定义以下内容:

(define variable-10-20 "some-value")

(define x 10)
(define y 20)

有没有办法让我写 variable-x-y 并返回 "some-value" ?

编辑 2 这是我要实现的简化代码。它所做的是将每个单独的元素递归地读入一个局部变量,然后可以在它全部被“读入”后使用。我敢肯定,如果您使用 here 找到的方法调整代码,它应该可以正常工作。

(define (matrix->variables matrix)
  (local [(define (matrix2->variables/acc matrix2 x y)
            (cond
              [;; the entire matrix has "extracted" it's elements into variables
               (empty? matrix2)
               #|This is where the main program goes for using the variables|#]
              [;; the first row has "extracted" it's elements into variables
               (empty? (first matrix2))
               (matrix2->variables/acc (rest matrix2) 0 (add1 y))]
              [else (local [(define element-x-y "some-value")]
                      ;; Here is where I got stuck since I couldn't find a way to
                      ;; name the variable being created (element-x-y)
                      (matrix2->variables/acc
                       (cons (rest (first matrix2)) (rest matrix2))
                       (add1 x) y))]))]
    (matrix2->variables/acc matrix 0 0)))

【问题讨论】:

  • 另外,如果只给出变量 xy,我将如何检索 variable-x-y 的值b>(在程序内)?我会更新问题以反映这一点。
  • 如果不是因为我还不允许在我的程序中使用 define-syntax,这将是完美的。不管怎样,谢谢你指点我。

标签: scheme racket variable-assignment


【解决方案1】:

我认为您误解了变量定义的工作原理。当你创建一个变量名时,你必须知道如何调用它,你不能动态地define名字。

也许用于存储绑定的哈希表会很有用,它有点类似于您所要求的并模拟具有动态定义的变量 - 但我仍然不确定 为什么 你想这样做,听起来对我来说更像是XY problem。试试这个:

(define (create-key var1 var2)
  (string->symbol
   (string-append 
    "variable-"
    (number->string var1)
    "-"
    (number->string var2))))

; create a new "variable"
(define x 10)
(define y 20)
(create-key x y)
=> 'variable-10-20

; use a hash for storing "variables"
(define vars (make-hash))

; add a new "variable" to hash
(hash-set! vars (create-key x y) "some-value")

; retrieve the "variable" value from hash
(hash-ref vars 'variable-10-20)
=> "some-value"

【讨论】:

  • 所以基本上在我的程序中,我正在使用一个矩阵,我不想继续处理矩阵来获取它的值。我正在考虑将每个元素定义为一个变量,以便在我使用它时可以调用它。
  • 将矩阵实现为向量的向量,并使用其索引引用每个元素,这在大多数编程语言中都是这样做的。为此创建动态变量是完全错误的。
  • 是的,这一个XY问题:P
  • 是的,到目前为止我还没有听说过 XY 问题。抱歉,这是我在 Stackoverflow 上发布的第一个问题。也感谢您向我推荐它,我下次发帖时会记住这一点。您知道检索矩阵值的更有效方法吗?我目前仅限于使用列表来实现矩阵。
  • 向量会更有效,因为它是为快速访问给定索引的元素而设计的。列表也可以,但查找带有索引的元素会更昂贵,因为必须先遍历它之前的所有元素
【解决方案2】:

与 López 先生所说的相反,变量名称可以在运行时决定,但只能在顶层或模块级别决定。在模块中执行此操作:

(compile-enforce-module-constants #f)
(eval `(define ,(string->symbol "foo") 'bar) (current-namespace))

这是对还是错完全是一个单独的问题。

当您尝试访问这些变量时会遇到同样的问题,因此您也必须在那里使用eval。您不能使用provide 导出这些变量。

【讨论】:

  • 嗯...我还没有触及任何涉及 eval 的东西。使用eval和这里使用的方法有什么区别:stackoverflow.com/questions/21176956/…
  • define-syntax 表示您正在编写宏,并且宏在编译时被扩展。 eval 发生在运行时。在 Scheme 和 Common Lisp 中,您可以稍微模糊一下区别,因为编译/宏扩展和运行可以交错,但在 Racket 中,您首先在与运行时环境隔离的特殊编译时环境中编译模块,并且然后在字节码文件写入磁盘后运行它们。所以你不能有一个宏使用一个字符串,其值在运行时才可用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-06
  • 2013-03-10
  • 2017-06-10
  • 2015-03-15
  • 2017-06-29
相关资源
最近更新 更多