วิธีสร้าง: คำหลัก?


16

ถาม: มีวิธีสร้างและใช้:keywordsอย่างไร?

พิจารณาความพยายาม (ไร้เดียงสาที่เห็นได้ชัด) ในการเข้าถึงของเล่น alist ต่อไปนี้:

(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

คีย์แรกทำงานตามที่คาดไว้ แต่คีย์ที่สองไม่ทำงาน ตราบเท่าที่ไม่มีmake-keywordฟังก์ชั่นที่ชัดเจนใครจะสร้างและใช้คำหลักได้อย่างไร

แรงจูงใจดั้งเดิม: ฉันต้องแปลงสตริงเป็นคีย์ค้นหาที่เป็นสัญลักษณ์ซึ่งฉันสามารถใช้งานputคุณสมบัติได้

ในกระบวนการกำหนดคำถามนี้ฉันได้รับอย่างน้อยส่วนหนึ่งของคำตอบซึ่งฉันโพสต์แยกต่างหาก ฉันหวังว่าจิตใจที่แจ่มใสกว่าที่ฉันจะปรับปรุงได้


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

คำตอบ:


9

คุณมีสิทธิ์ที่make-symbolจะสร้างคำหลักที่ไม่ได้eqอยู่กับคำหลักที่มีอยู่และinternอาจทำให้เกิดความสับสนกับสัญลักษณ์ใหม่ทั่วโลก ในระหว่างนั้นคุณจะได้intern-softรับผลตอบแทนถ้ามันถูกสร้างขึ้นหรือnilถ้ามันไม่ได้:

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

สิ่งนี้ควรเหมาะสมกับจุดประสงค์ของคุณ: หากคำหลักไม่มีอยู่คำหลักนั้นจะไม่สามารถปรากฏใน alist ได้ดังนั้นจึงไม่จำเป็นต้องสร้างมันขึ้นมาเพื่อตรวจสอบว่ามีหรือไม่ สิ่งที่ต้องการ:

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

เคลฟเวอร์ - ฉันเคยเห็นintern-softแต่ไม่เคยคิดที่จะใช้วิธีนี้
แดน

6

บางทีฉันไม่เข้าใจคำถามอย่างถูกต้อง แต่ถ้าคุณต้องการคำหลัก (เช่นคุณต้องการที่จะตอบสนองkeywordp) แล้วคุณต้องการสัญลักษณ์ที่จะฝึกงานใน obarray ทั่วโลกobarray ,

มันจะต้องถูกฝึกงานที่นั่นเพื่อตอบสนองkeywordpAFAICT และC-h f keywordpพูดอย่างนั้น

ดังนั้นคำตอบสำหรับคำถามของคุณ AFAICT ที่เป็นเพียงการใช้งานintern

ฉันรู้สึกว่าคุณไม่ได้ถามคำถามจริงของคุณ - ดูเหมือนคำถาม XY คุณพยายามทำอะไรจริงๆ (อาจเป็นคำถามที่แยกต่างหาก)

[เพื่อตอบความคิดเห็นของคุณว่าการฝึกงาน " ไม่:keywordเฉพาะเจาะจงเนื่องจากมันใช้กับสัญลักษณ์ทั้งหมด ": ถูกต้องการฝึกงานไม่ได้เฉพาะเจาะจงกับคำหลัก แต่การฝึกงาน (ในobarray) และการใช้symbol-nameที่ขึ้นต้นด้วย:นั้นเฉพาะเจาะจงกับคำหลัก]


มันเป็นคำถาม XY ที่แน่นอนที่สุดในแง่ที่ว่าฉันพยายามที่จะ Y แต่ได้รับความสนใจใน X ในความพยายามของฉันที่จะได้รับ Y ฉันขอให้ฉันคิดเกี่ยวกับวิธีการวางคำถามเกี่ยวกับ Y ในแบบที่มันเป็น มีประโยชน์ต่อผู้อื่นเช่นกัน
แดน

ยิ่งใหญ่ นั่นจะเป็นประโยชน์ ขอบคุณ.
ดึง

2

นี่คือคำตอบบางส่วนของคำถามนี้ รุ่นสั้นและไม่ได้ทั้งความพึงพอใจน่าจะเป็น: internการใช้งาน

:key-1 ตอบสนองทั้งสองอย่าง:

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

ในขณะที่(make-symbol ":key-1")สร้างความพึงพอใจเป็นครั้งแรก แต่ไม่ใช่วินาที

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

ตอนนี้ docstring สำหรับmake-symbolบอกว่ามันจะ:

ส่งคืนสัญลักษณ์ที่ไม่ได้ถูกจัดสรรใหม่ซึ่งมีชื่อว่า NAME

Mmmkay และ docstring สำหรับkeywordpบอกว่ามันจะ:

ส่งคืนtถ้า OBJECT เป็นคำหลัก ซึ่งหมายความว่าเป็นสัญลักษณ์ที่มีชื่อพิมพ์เริ่มต้นด้วย: interned ใน obarray เริ่มต้น

ดังนั้นดูเหมือนว่าinternจะทำงาน:

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

เพราะinternจะ:

ส่งคืนสัญลักษณ์แบบบัญญัติซึ่งชื่อ STRING หากไม่มีจะมีการสร้างขึ้นใหม่โดยฟังก์ชั่นนี้และส่งคืน อาร์กิวเมนต์ตัวเลือกที่สองระบุ obarray ที่จะใช้ obarrayเป็นค่าเริ่มต้นค่าของ

แต่สิ่งนี้ดูเหมือนจะไม่:keywordเจาะจงเพราะมันใช้กับสัญลักษณ์ทั้งหมด ตามค่าเริ่มต้นดูเหมือนว่าจะก่อให้เกิดมลพิษทั่วโลกobarrayซึ่งอาจจะใช่หรือไม่ใช่เรื่องใหญ่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.