Nasıl oluşturulur: anahtar kelimeler?


16

S: Kişi nasıl yaratır ve kullanır :keywords?

Aşağıdaki oyuncak alist'e erişmek için (naif, görünüşte) bir girişim düşünün:

(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

İlk anahtar beklendiği gibi çalışır, ancak ikinci anahtar çalışmaz. Belirgin bir make-keywordfonksiyon olmadığı sürece , bir anahtar kelime nasıl oluşturulur ve kullanılır?

Özgün motivasyon: Bir dizeyi, putözellikleri kullanabileceğim bir sembol olan bir arama anahtarına dönüştürmem gerekiyor .

Bu soruyu formüle etme sürecinde, cevabın en azından bir kısmına ayrıldım, ki bu da ayrı olarak gönderiyorum. Benimkinden daha parlak zihinlerin gelişmesini umuyorum.


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

Yanıtlar:


9

Haklısınız o vardır make-symbololmayan bir anahtar kelime yaratacak eqvarolan herhangi bir anahtar kelimeye ve internyeni sembol ile küresel obarray kirletmez olabilir. Bunların arasında intern-soft, zaten oluşturulmuşsa veya oluşturmamışsa sembolü döndüren nilvar:

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

Bu sizin amacınız için uygun olmalıdır: anahtar kelime mevcut değilse, listede bulunamaz, bu yüzden sadece orada olup olmadığını kontrol etmek için onu oluşturmaya gerek yoktur. Gibi bir şey:

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

Zeki - Görmüştüm intern-softama bu şekilde kullanmayı düşünmemiştim.
Dan

6

Belki de soruyu doğru anlamıyorum. Ama eğer bir anahtar kelime istiyorum (yani sizi tatmin istediğiniz keywordp) o zaman sembol küresel obarray staj olmak istiyorum , obarray.

Bu gerekir karşılamak için orada staj edilmesi keywordp, AFAICT ve C-h f keywordpöyle diyor.

Yani sorunuzun cevabı AFAICT, sadece kullanmaktırintern .

Belki gerçek sorunuzu sormuyorsunuz gibi hissediyorum - bir XY sorusuna benziyor. Gerçekten ne yapmaya çalışıyorsun? (Belki bunu ayrı bir soru olarak ortaya koyun.)

[Interning'in " tüm semboller için geçerli olduğu gibi spesifik olmadığı:keyword " yorumunuza yanıt olarak : Doğru, interning anahtar kelimelere özgü değildir. Ancak, interning (in obarray) ve symbol-namebununla başlayan bir :anahtar kelimeyi kullanmak anahtar kelimelere özgüdür.]


Kesinlikle Y'ye çalışıyorum anlamında bir XY sorusu, ama Y'ye ulaşma girişimimde X ile gerçekten ilgilendim. Y ile ilgili soruyu, başkaları için de yararlı.
Dan

Harika. Bu yardımcı olacaktır. Teşekkür.
Drew

2

İşte bu soruya kısmi bir cevap. Kısa ve tamamen tatmin edici olmayan versiyon: kullanım intern.

:key-1 ikisini de tatmin eder:

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

İlkini (make-symbol ":key-1")yerine getirirken ikinci değil:

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

Şimdi, için doktora make-symboldiyor ki:

Adı NAME olan, yeni atanmış, sınırlanmamış bir sembol döndürün.

Mmmkay, ve doktora keywordpşunu yapacağını söylüyor:

İade tOBJE bir anahtar kelime ise. Bu : , ilk obarrayde stajyeli olarak başlayan bir yazdırma adına sahip bir sembol olduğu anlamına gelir .

Yani internişe yarayacak gibi görünüyor :

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

Çünkü intern:

Adı STRING olan standart sembolü döndür. Hiçbiri yoksa, biri bu işlev tarafından oluşturulur ve döndürülür. İkinci bir isteğe bağlı bağımsız değişken, kullanılacak engellemeyi belirtir; varsayılan olarak obarray.

Ancak :keyword, tüm semboller için geçerli olduğu için bu belirli görünmüyor . Varsayılan olarak, obarrayA Big Deal olabilecek ya da olmayabilecek olan küreselleri de kirletmektedir .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.