سؤال

وعندما أحاول إضافة البيانات الوصفية لتسلسل كسول لا حصر له في كلوجر، وأحصل على تجاوز سعة مكدس، وإذا كنت خلع الفوقية، ثم يعمل على ما يرام. لماذا لا يضيف الماكرو with-meta كسر يليها كسول؟

أولا تهيئة بعدها لا حصر له من عدد لطيفة جدا:

(defn good []
  (lazy-seq 
    (cons 42
      (good))))

user> (take 5 (good))
(42 42 42 42 42)

وبعد ذلك، وإضافة بعض بيانات التعريف لكل من الحالات كسول وما يليها:

(defn bad []
  (lazy-seq 
    (cons 42
      (with-meta 
       (bad)
       {:padding 4}))))


user> (take 5 (bad))
java.lang.StackOverflowError (NO_SOURCE_FILE:0)
  [Thrown class clojure.lang.Compiler$CompilerException]

وحاول نقل البيانات الفوقية مستوى واحد:

(defn also-bad []
  (with-meta 
   (lazy-seq 
     (cons 42
       (also-bad)))
   {:padding 4}))

user> (take 5 (foo))
java.lang.StackOverflowError (NO_SOURCE_FILE:0)
  [Thrown class clojure.lang.Compiler$CompilerException]

وهنا مثال على بيانات التعريف على تسلسل محدود:

(defn also-works []
     (lazy-seq 
       (cons 4 
         (with-meta 
          () 
          {:a 5}))))

user> (also-works)
(4)
user> (meta (rest (also-works)))
{:a 5}
user> 
هل كانت مفيدة؟

المحلول

ولأن LazySeq تقيم الهيئة في أقرب وقت كما تسمونه withMeta على LazySeq. تفقد الكسل الخاص بك.

public final class LazySeq extends Obj implements ISeq, List{
    ...
    public Obj withMeta(IPersistentMap meta){
        return new LazySeq(meta, seq());
    }
    ...
}

وseq() يقيم جسم يليها كسول إذا لم يكن قد تم تقييمها. التعليمات البرمجية أعلاه يحتفظ يدعو with-meta على seqs كسول المتعاقبة، التي يقيم كل منهم حتى ينفجر المكدس. أنا لا أعتقد أن هناك حاليا أي طريقة لإضافة البيانات الوصفية إلى يليها كسول دون وقوع ذلك لتقييم الجسم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top