سؤال

أنا تريد أن تجعل من المحلية مثيل جافا Scanner الدرجة في clojure البرنامج.لماذا لا تعمل:

; gives me:  count not supported on this type: Symbol 
(let s (new Scanner "a b c"))

ولكن سوف اسمحوا لي أن إنشاء مثيل عالميا مثل هذا:

(def s (new Scanner "a b c"))

كنت تحت انطباع أن الفرق الوحيد كان في نطاق ما..ما هو الفرق بين let و def?

هل كانت مفيدة؟

المحلول

والمشكلة هي أن استخدامك لlet خاطئ.

ودعونا يعمل مثل هذا:

(let [identifier (expr)])

وهكذا سبيل المثال يجب أن يكون لديك شيء من هذا القبيل:

(let [s (Scanner. "a b c")]
  (exprs))

ويمكنك فقط استخدام الارتباطات المعجمية جعل مع let ضمن نطاق أبلاغ (فتح وإغلاق أقواس). مجرد السماح بإنشاء مجموعة من الارتباطات المعجمية. يمكنني استخدام مواطنه لصنع ملزمة العالمية، ويتيح للربط شيء أريد فقط في نطاق اسمحوا لأنها تحافظ على نظافة الأشياء. ديهما استخداماتها.

ملحوظة:. (. الدرجة) هو نفسه (الدرجة الجديدة)، انها مجرد نحوي السكر

نصائح أخرى

وLET ليست "جعل ملزمة معجمية في النطاق الحالي"، ولكن "جعل نطاق المفردات الجديدة مع الارتباطات التالية".

(let [s (foo whatever)]
  ;; s is bound here
  )
;; but not here
(def s (foo whatever))
;; s is bound here

وبناء الجملة الصحيح:

(let [s (Scanner. "a b c")] ...)

مبسطة: def هو العالمية الثوابت ، السماح هو المتغيرات المحلية.

وبناء الجملة بالنسبة لهم هو مختلف، حتى إذا كانت متعلقة المعاني.

واسمحوا يأخذ <م> قائمة الارتباطات (أزواج قيمة اسم) تليها عبارات لتقييم في سياق تلك ملزمة.

ومواطنه يستغرق سوى واحدة ملزمة، ليست قائمة، وإضافته إلى السياق العالمي.

هل يمكن التفكير في let كما نحوي السكر لإنشاء نطاق المفردات الجديدة مع fn ثم تطبيقه على الفور:

(let [a 3 b 7] (* a b))  ; 21
; vs.
((fn [a b] (* a b)) 3 7) ; 21

وهكذا يمكن تنفيذ let مع بسيطة وfn الكلي و:

(defmacro fnlet [bindings & body]
  ((fn [pairs]
    `((fn [~@(map first pairs)] ~@body) ~@(map last pairs)))
   (partition 2 bindings)))

(fnlet [a 3 b 7] (* a b)) ; 21
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top