2

作为用 Racket 编写的 servlet 的一部分,我想创建一个函数,将请求绑定(以字符串作为键和值的 hasheq 表的形式)转换为 SQL 表行(再次编写为带字符串的 hasheq 表作为键和 sql 类型作为值)。当相关函数收到两个哈希表时,这一切似乎都按预期工作,此时它失败并出现以下错误:

请求绑定是:

'#hasheq(("lastname" . "Smith")
         ("firstname" . "John")
          ("birthdate" . "1900-10-25"))

列类型是

'#hasheq(("lastname" . "character varying")
         ("firstname" . "character varying")
         ("birthdate" . "date"))

错误信息是:

Servlet (@ /<... servlet URL ...>) exception:
hash-ref: no value found for key
  key: "lastname"

奇怪的是,如果将这些哈希表与相关代码片段一起粘贴到 DrRacket 提示符,它运行时不会产生错误

The value "Smith" needs to be converted to type "character varying"
The value "John" needs to be converted to type "character varying"
The value "1900-10-25" needs to be converted to type "date"

我做错了什么?任何帮助是极大的赞赏!这是代码:

#lang racket

(define bindings-hash
  '#hasheq(("lastname" . "Smith")
           ("firstname" . "John")
           ("birthdate" . "1900-10-25")))

(define types-hash
  '#hasheq(("lastname" . "character varying")
           ("firstname" . "character varying")
           ("birthdate" . "date")))

(define (test)
  (eprintf "The request bindings are \n~v\n" bindings-hash)
  (eprintf "The column types are \n~v\n" types-hash)
  (for ([(this-key this-value) (in-hash bindings-hash)])
    (eprintf "The value ~v needs to be converted to type ~v\n"
             this-value
         (hash-ref types-hash this-key))))

(test)
4

3 回答 3

4

使用hash-equal字符串时使用。符号保证可以与 . 一起使用eq?,但字符串必须与 . 进行比较equal?

问题是结果(eq? "foo" "foo")是未定义的。

于 2012-11-03T10:20:36.767 回答
3

这是一个实际的答案 - 对您问题的另一部分:为什么将代码粘贴到 DrRacket 中的 REPL?

字符串文字的多种用途"lastname"正在“实习”成为内存中的同一个 Racket 对象。结果,它们是eq?

(eq? "lastname" "lastname")
=> #t

但是在你真正的 servlet 程序中,哈希中的字符串值来自内存中的两个不同的 Racket 对象,即使它们碰巧具有相同的值。例如,让我们构造一个字符串,其"lastname"值为(string-append "last" "name"). 如果我们将与字符串文字进行比较,"lastname"它们不是 eq?

(eq? "lastname" (string-append "last" "name"))
=> #f

它们在内存中不是同一个对象,所以它们不是 eq?. 这两个不同的对象确实具有相同的值,所以它们 equal?

于 2012-11-03T13:48:46.947 回答
2

[这实际上只是对@soegaard 发布的出色答案的评论。我将其发布为“答案”只是为了获得体面的多行代码格式。]

要使用 比较键的哈希值equal?,您可以使用

#hash([key0 . value0]
      [key1 . value1])

你也可以通过说创建完全相同的东西

(hash key0 value0
      key1 value1)

如果你把它分成几行,成对的分组同样清晰,但没有所有额外的括号和点。

第一种方式比较传统,看起来像一个经典的关联列表。我发现自己更喜欢第二种风格。

于 2012-11-03T13:35:24.520 回答