2010-06-24 26 views
14

'de veri yapısı uygulama detaylarından soyutlama Birden fazla alt yapıları ile Clojure karmaşık bir veri yapısı geliştiriyorum.Clojure

Bu yapıyı zaman içinde genişletmek istediğimi biliyorum ve zaman zaman veri yapısının farklı kullanıcılarını kırmadan iç yapıyı değiştirmek isteyebilir (örneğin, bir hastayı bir hasaşta değiştirmek istiyorum). bazı performans nedenleriyle indeksleme yapısının tür veya birleştirmek bir Java tipi)

Benim şu anki düşünce geçerli:

  • bir mini kütüphane oluşturma çeşitli erişimci yöntemleri ile genel yapısı için bir protokol tanımlayın veri yapısında gezinen işlevler e .g. Ben endişeliyim olsa (sorgu-altyapı-abc Param1 param2)
  • , mini-kütüphane

Ben bu işe yarayacak kullanmak tanımlanan protokol yöntemlerle defrecord veya deftype kullanarak veri yapısını, uygulamak oldukça "tutkal" kodu gibi görünmeye başlıyor. Ayrıca muhtemelen nesneye yönelik yaklaşımlarla daha fazla yakınlığımı da yansıtıyor.

Clojure'da bunu yapmanın önerilen yolu nedir?

cevap

11

Bence bu, deftype yoluna gidebilir, ancak erişim yöntemleri üzerinde bir geçiş yapacağım. Bunun yerine, clojure.lang.ILookup ve clojure.lang.Associative; Bunlar, sizin türünüz için uygularsanız, get/get-in ve assoc/assoc-in'u kullanmanıza izin verecek, çok daha çok yönlü bir çözüm sağlayan arabirimlerdir (yalnızca altta yatan uygulamayı değiştiremezsiniz, aynı zamanda belki de Clojure'nin standart koleksiyon kütüphanesinin üstüne inşa edilmiş fonksiyonlar, yapılarınızı manipüle etmek için).

Birkaç şey not: Muhtemelen ILookup, Associative, IPersistentMap ve java.util.Map standart defrecord uygulamaları ile get, assoc & Co kullanarak, defrecord ile başlamalıdır

  1. . Bununla oldukça uzun bir yoldan gidebilirsin.

    Bunlar artık/yeterli değilse, emit-defrecord (Clojure kaynaklarında core_deftype.clj'da tanımlanan özel bir işlev) kaynaklarına bakın. Oldukça karmaşık, ama uygulamak için neye ihtiyacınız olabileceği hakkında bir fikir verecektir.

  2. Ne deftype ne de defrecord şu anda sizin için herhangi bir fabrika fonksiyonlarını tanımlamak, ancak bunu kendiniz muhtemelen yapmalıdır. Sanite kontrolü bu işlevlerin (ve/veya ilgili testlerin) içine girer.

  3. daha kavramsal karmaşık işlemler elbette get & Co.

Ah temeli üzerine inşa protokol işlevleri için mükemmel bir uyum vardır ve bir örnek için Clojure en kaynaklarda gvec.clj de bakabilirsiniz deftype kullanılarak yazılmış bazı ciddi veri yapısı kodları nasıl görünebilir.Buradaki karmaşıklık, soruyu açıkladığınızdan farklı bir türdedir, ancak yine de, şu anda kamusal tüketim için mevcut olan Clojure'daki özel veri yapısı programlamasının birkaç örneğinden biridir (ve elbette mükemmel kalite kodudur).

Tabii ki bu benim sezgemin şu anda bana söylediği şey. Bu aşamada yerleşik deyimler biçiminde çok fazla bir şey olmadığından emin değilim, deftype ile aslında ne de olsa serbest bırakılmadı. :-)

+0

Teşekkürler Michal! Her zamanki gibi anlayışlı :-) kesinlikle ILookup ve Associative seçeneklerine bakacaktır – mikera

+0

Bu çok faydalı bir cevap! Ancak yaklaşık üç yıl sonra, şu anda 1.5 sürümündeki özelliği temel alarak bunu güncellemek (veya yeni bir cevap oluşturmak) harika olacaktır. Fark ettiğim bir şey şu ki, 'defrecord' artık diğer fonksiyonların bu cevabı nasıl etkileyeceğinden emin değil, fabrika fonksiyonlarını yayar. –

+0

Bu cevabın ayrıca bir güncelleme de kullanabileceğini düşünüyorum - O'Reily Clojure kitabı şimdi bile clojure's defrecord'ın fabrika fonksiyonları yarattığını söylüyor. – djhaskin987