作为用Racket编写的servlet的一部分,我想创建一个函数,将请求绑定(以hasheq-table的形式,字符串作为键和值)转换为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)
3 回答
使用字符串时使用
hash-equal
. 符号保证与eq?
一起使用,但必须将字符串与equal?
进行比较 .问题是
(eq? "foo" "foo")
的结果是未定义的 .这是一个实际的答案 - 问题的另一部分:为什么它将代码粘贴到DrRacket中的REPL?
字符串文字
"lastname"
的多次使用使"interned"成为内存中的相同Racket对象 . 结果,他们是eq?
:但是在真正的servlet程序中,哈希中的字符串值来自内存中的两个不同的Racket对象,即使它们碰巧具有相同的值 . 例如,让我们通过
(string-append "last" "name")
构造一个值为"lastname"
的字符串 . 如果我们将它与字符串文字"lastname"
进行比较,那么它们不是eq?
他们're not the same object in memory, so they'不是
eq?
. 两个不同的对象具有相同的值,因此它们是equal?
.[这只是对@soegaard发布的优秀答案的评论 . 我将它发布为"answer"只是为了获得合适的多行代码格式 . ]
要使用
equal?
创建比较键的哈希,您可以使用您也可以通过说出来创建完全相同的东西
如果你将它分割成线条,对的分组就一样清晰,但没有所有额外的括号和点 .
第一种方式更传统,看起来像一个经典的关联列表 . 我发现自己更喜欢第二种风格 .