首页 文章

球拍:在hasheq错误中找不到键值

提问于
浏览
1

作为用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 回答

  • 4

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

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

  • 3

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

    字符串文字 "lastname" 的多次使用使"interned"成为内存中的相同Racket对象 . 结果,他们是 eq?

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

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

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

    他们're not the same object in memory, so they'不是 eq? . 两个不同的对象具有相同的值,因此它们是 equal? .

  • 2

    [这只是对@soegaard发布的优秀答案的评论 . 我将它发布为"answer"只是为了获得合适的多行代码格式 . ]

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

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

    您也可以通过说出来创建完全相同的东西

    (hash key0 value0
          key1 value1)
    

    如果你将它分割成线条,对的分组就一样清晰,但没有所有额外的括号和点 .

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

相关问题