Cách tạo: từ khóa?


16

Q: Làm thế nào để tạo và sử dụng :keywords?

Hãy xem xét một nỗ lực (ngây thơ, rõ ràng) để truy cập vào đồ chơi sau đây:

(setf alist '((:key-1 "Key no. 1")
              (:key-2 "Key no. 2")))

(assq :key-1 alist)                 ; => (:key-1 "Key no. 1")
(assq (make-symbol ":key-1") alist) ; => nil

Khóa đầu tiên hoạt động như mong đợi, nhưng khóa thứ hai thì không. Trong chừng mực không có make-keywordchức năng rõ ràng , làm thế nào để tạo và sử dụng một từ khóa?

Động lực ban đầu: Tôi cần chuyển đổi một chuỗi thành một khóa tra cứu là biểu tượng mà tôi có thể tạo ra put.

Trong quá trình hình thành câu hỏi này, tôi đã nhận được ít nhất một phần câu trả lời mà tôi đang đăng riêng. Tôi hy vọng tâm trí sáng sủa hơn tôi có thể cải thiện nó.


1
(eq :foo (read ":foo"))
abo-abo

Câu trả lời:


9

Bạn đúng rằng make-symbolsẽ tạo ra một từ khóa không phải là eqbất kỳ từ khóa hiện có nào và interncó thể gây ô nhiễm sự phản đối toàn cầu với biểu tượng mới. Ở giữa những cái đó, bạn có intern-soft, trả về biểu tượng nếu nó đã được tạo hoặc nilnếu nó không có:

ELISP> (intern-soft ":key-1")
nil
ELISP> :key-1
:key-1
ELISP> (intern-soft ":key-1")
:key-1

Điều này phải phù hợp với mục đích của bạn: nếu từ khóa không tồn tại, nó không thể xuất hiện trong danh sách, vì vậy không cần phải tạo từ khóa chỉ để kiểm tra xem nó có ở đó không. Cái gì đó như:

(let ((maybe-keyword (intern-soft ":key-1")))
  (and maybe-keyword (assq maybe-keyword alist)))

Thông minh - Tôi đã thấy intern-softnhưng chưa nghĩ sẽ sử dụng nó theo cách này.
Dân

6

Có lẽ tôi không hiểu câu hỏi chính xác. Nhưng nếu bạn muốn có một từ khóa (ví dụ, bạn muốn thỏa mãn keywordp) sau đó bạn muốn biểu tượng để được thực tập nội trú trong obarray toàn cầu , obarray.

phải được thực tập ở đó để đáp ứng keywordp, AFAICT, và C-h f keywordpnói như vậy.

Vì vậy, câu trả lời cho câu hỏi của bạn, AFAICT, chỉ là để sử dụngintern .

Tôi cảm thấy như bạn có lẽ không hỏi câu hỏi thực sự của bạn - có vẻ như một câu hỏi XY. Bạn thực sự đang cố gắng làm gì? (Có thể đặt ra đó là một câu hỏi riêng biệt.)

[Trả lời nhận xét của bạn rằng thực tập " không :keywordcụ thể, vì nó áp dụng cho tất cả các biểu tượng ": Chính xác, thực tập không cụ thể cho các từ khóa. Nhưng thực tập (trong obarray) và sử dụng một symbol-namebắt đầu bằng :là cụ thể cho các từ khóa.]


Đó chắc chắn là một câu hỏi XY theo nghĩa là tôi đang cố gắng với Y, nhưng thực sự quan tâm đến X trong nỗ lực tìm đến Y. Hãy để tôi suy nghĩ về cách đặt câu hỏi về Y theo cách mà nó hữu ích cho người khác là tốt.
Dân

Tuyệt quá. Điều đó sẽ hữu ích. Cám ơn.
vẽ

2

Đây là một câu trả lời cho câu hỏi này. Phiên bản ngắn và không hoàn toàn thỏa mãn dường như là: sử dụng intern.

:key-1 thỏa mãn cả hai:

(symbolp :key-1)                    ; => t
(keywordp :key-1)                   ; => t

Trong khi (make-symbol ":key-1")thỏa mãn thứ nhất nhưng không phải thứ hai:

(symbolp (make-symbol ":key-1"))    ; => t
(keywordp (make-symbol ":key-1"))   ; => nil

Bây giờ, chuỗi doc cho make-symbolbiết nó sẽ:

Trả về một biểu tượng không được phân bổ mới được phân bổ có tên là NAME.

Mmmkay và chuỗi cho keywordpbiết rằng nó sẽ:

Trả về tnếu ĐỐI TƯỢNG là một từ khóa. Điều này có nghĩa là nó là một biểu tượng có tên in bắt đầu bằng : nội dung trong obarray ban đầu.

Vì vậy, nó xuất hiện internsẽ làm việc:

(assq (intern ":key-1") alist)      ; => (:key-1 "Key no. 1")

Bởi vì internsẽ

Trả lại biểu tượng chính tắc có tên là CHUINGI. Nếu không có, một cái được tạo bởi hàm này và trả về. Đối số tùy chọn thứ hai chỉ định obarray sẽ sử dụng; nó mặc định là giá trị của obarray.

Nhưng điều này dường như không :keywordcụ thể, vì nó áp dụng cho tất cả các biểu tượng. Theo mặc định, nó cũng có vẻ gây ô nhiễm toàn cầu obarray, có thể hoặc không phải là một Thỏa thuận lớn.

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.