Hashtable Racket:在hasheq错误中找不到键的值

Hashtable Racket:在hasheq错误中找不到键的值,hashtable,racket,Hashtable,Racket,作为用Racket编写的servlet的一部分,我想创建一个函数,将请求绑定(以字符串作为键和值的hasheq表的形式)转换为SQL表行(再次编写为字符串作为键、SQL类型作为值的hasheq表)。直到相关函数接收到两个哈希表时,这一切似乎都按预期工作,此时它失败并出现以下错误: 请求绑定包括: '#hasheq(("lastname" . "Smith") ("firstname" . "John") ("birthdate" . "1900-10-25"

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

请求绑定包括:

'#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"
我做错了什么?非常感谢您的帮助!代码如下:

#朗球拍
(定义绑定哈希)
#hasheq((“姓氏”“史密斯”)
(“名字”,“约翰”)
(“出生日期”1900-10-25)
(定义散列类型)
“#hasheq((“姓氏”,“字符变化”)
(“名字”,“字符变化”)
(“生日”。“日期”))
(定义(测试)
(eprintf“请求绑定是\n~v\n”绑定哈希)
(eprintf“列类型为\n~v\n”散列类型)
(对于([(此键此值)(在散列绑定散列中)])
(eprintf“值~v需要转换为类型~v\n”
此值
(哈希引用类型哈希此键)))
(测试)

处理字符串时使用
哈希相等
。符号保证与
eq?
一起使用,但字符串必须与
equal?
进行比较

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

[这实际上只是对@soegaard发布的优秀答案的评论。我将其作为“答案”发布,只是为了获得良好的多行代码格式。]

要使用
equal?
创建比较键的哈希,可以使用

#hash([key0 . value0]
      [key1 . value1])
你也可以通过说

(hash key0 value0
      key1 value1)
如果将其拆分为多行,则对的分组同样清晰,但没有所有额外的括号和点

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

这是对您问题的另一部分的实际回答:为什么它可以将代码粘贴到DrRacket中的REPL

字符串literal
“lastname”
的多次使用被“interned”为内存中的同一个球拍对象。因此,它们是
eq?

(eq? "lastname" "lastname")
=> #t
但在真正的servlet程序中,哈希中的字符串值来自内存中的两个不同的Racket对象,即使它们碰巧具有相同的值。例如,让我们通过
(字符串附加“last”“name”)
构造一个值为
“lastname”的字符串。如果我们将其与字符串literal
“lastname”
进行比较,它们就不是
eq?

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

它们在内存中不是同一个对象,因此它们不是
eq?
。这两个不同的对象具有相同的值,因此它们是相等的。

谢谢您的建议!你的意思是我应该使用不同类型的相等性测试还是不同类型的散列?我在代码中没有任何地方可以依赖于平等性测试。我使用“string=?”来比较字符串。它和字符串的“eq”不一样吗?一种不同类型的散列。您的密钥是字符串,因此您应该使用
哈希相等
。谢谢!我使用(makehasheq)创建所有哈希表。我应该用(hasheqv)来代替吗?是的。或者
使散列相等
。不客气。要接受答案,请单击“向上”和“向下”投票下方的标记。看见
(eq? "lastname" (string-append "last" "name"))
=> #f