tại sao sẽ không nhận được giá trị của khóa của tôi?


8

Có kinh nghiệm lập trình lisp, lược đồ, clojure chuyển sang elisp từ python để tự động hóa các công việc cơ bản, hàng ngày, cơ bản: Tôi đã có một bất ngờ lớn từ những điều sau đây ielm

ELISP> (setq h2 (make-hash-table))
#s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8 data ())
ELISP> (puthash "a" 1 h2)
1 (#o1, #x1, ?\C-a)
ELISP> (gethash "a" h2)
nil

Huh? Khóa và giá trị dường như có mặt:

ELISP> h2
#s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8 data ("a" 1))

/ tát trán. Tôi phải thiếu một cái gì đó hoàn toàn rõ ràng. Thông tin nói:

-- Function: gethash key table &optional default
 This function looks up KEY in TABLE, and returns its associated
 VALUE—or DEFAULT, if KEY has no association in TABLE.

tuyệt quá. Hãy xem liệu chúng ta có thể gethashtrả lại bất cứ thứ gì ngoài nil:

ELISP> (gethash "a" h2 'fubar) 
fubar

ồ Ok, tôi rất ngốc hơn tôi nghĩ. Tôi đang làm gì vậy?

Câu trả lời:


13

Kiểm tra thành viên mặc định cho một bảng băm là eql. Nếu bạn muốn sử dụng một chuỗi làm khóa, equalthay vào đó , hãy đặt nó thành :

(setf hash (make-hash-table :test #'equal))
(puthash "a" 1 hash)
(gethash "a" hash)                      ; ==> 1

Để tham khảo, đây là phần có liên quan của chuỗi:

make-hash-table là một hàm dựng sẵn trong 'mã nguồn C'.

(make-hash-table &rest KEYWORD-ARGS)

Tạo và trả về một bảng băm mới.

Đối số được chỉ định là cặp từ khóa / đối số. Các đối số sau được định nghĩa:

:testKIỂM TRA - KIỂM TRA phải là một biểu tượng chỉ định cách so sánh các khóa. Mặc định là eql. Được xác định trước là các bài kiểm tra eq, eqlequal. Các hàm băm và kiểm tra do người dùng cung cấp có thể được chỉ định thông qua define-hash-table-test.


Tôi đoán về mặt kỹ thuật bạn không truyền biểu tượng làm :testtham số trong ví dụ của mình ...
Sean

string-equalcó thể có một số lợi thế hơn equalnếu tôi biết bảng băm của tôi chỉ có các chuỗi như các khóa. Tôi không chắc tại sao elisp có cả hai string-equalequal, bởi vì equalcó thể được sử dụng bất kỳ nơi nào string-equalcó thể được sử dụng modulo, thực tế là string-equalném lỗi loại khi bạn không cung cấp cho chuỗi đó. Có lẽ đó là một hành vi mong muốn.
Reb.Cabin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.