ক্লোজুরে ফাংশন আর্গুমেন্টের জন্য কীভাবে ডিফল্ট মান তৈরি করতে হয়


127

আমি এই সঙ্গে আসা:

(ডিফেন স্ট্রিং-> পূর্ণসংখ্যা [স্ট্র্যান্ড এবং [বেস]]
  (পূর্ণসংখ্যা / পার্সিয়ান্ট স্ট্র (যদি (শূন্য? বেস) 10 বেস))

(স্ট্রিং-> পূর্ণসংখ্যার "10")
(স্ট্রিং-> পূর্ণসংখ্যা "এফএফ" 16)

তবে এটি করার আরও ভাল উপায় হতে হবে।

উত্তর:


170

স্বাক্ষরগুলি আরটিতে পৃথক হলে কোনও ফাংশনে একাধিক স্বাক্ষর থাকতে পারে। আপনি এটি ডিফল্ট মান সরবরাহ করতে ব্যবহার করতে পারেন।

(defn string->integer 
  ([s] (string->integer s 10))
  ([s base] (Integer/parseInt s base)))

নোট করুন যে ধরে নেওয়া falseএবং nilউভয়ই অ-মান হিসাবে বিবেচিত (if (nil? base) 10 base)হয় (if base base 10), এটি সংক্ষিপ্ত করা যেতে পারে বা আরও কিছুতেও হতে পারে (or base 10)


3
আমি মনে করি ফাংশনটির নামটি পুনরাবৃত্তি না (recur s 10)করে দ্বিতীয় পংক্তিতে বলা ভাল হবে । এটি ভবিষ্যতে ফাংশনটির নামকরণ করা আরও সহজ করে তুলবে। কেউ কি এই পরিস্থিতিতে এই পরিস্থিতিতে ব্যবহার না করার কোন কারণ জানেন ? recurstring->integerrecur
ররি ও'কেনে

10
দেখে মনে হচ্ছে এটি recurকেবল একই তাত্পর্য নিয়ে কাজ করে। যদি আপনি উপরে পুনরাবৃত্তি করার চেষ্টা করেন, উদাহরণস্বরূপ:java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 1 args, got: 2, compiling:
djhaskin987

এই একই ইস্যু মধ্যে দৌড়ে। এটি কি কেবল ফাংশনটি নিজেই কল করা অর্থাত (অর্থাত্ (string->integer s 10))?
কার্ট মুয়েলার

155

restক্লোজুর ১.২ [ রেফ ] থেকে আপনি মানচিত্র হিসাবে আর্গুমেন্টগুলিও গঠন করতে পারেন । এটি আপনাকে ফাংশন আর্গুমেন্টগুলির জন্য নাম এবং ডিফল্ট সরবরাহ করতে দেয়:

(defn string->integer [s & {:keys [base] :or {base 10}}]
    (Integer/parseInt s base))

এখন আপনি কল করতে পারেন

(string->integer "11")
=> 11

অথবা

(string->integer "11" :base 8)
=> 9

আপনি এখানে এটিকে কর্মে দেখতে পাবেন: https://github.com/Raynes/clavatar/blob/master/src/clavatar/core.clj (উদাহরণস্বরূপ)


1
পাইথনের পটভূমি থেকে আসাটি এত সহজে বুঝতে পারছেন :)
ড্যান

1
এটি গ্রহণযোগ্য উত্তরের চেয়ে বোঝা আরও সহজ ... এটি কি স্বীকৃত "ক্লুজুরিয়ান" উপায়? দয়া করে এই দস্তাবেজে যুক্ত করার বিষয়টি বিবেচনা করুন।
ড্রোগানস

1
এটিকে মোকাবেলায় সহায়তা করার জন্য আমি আনুষ্ঠানিক স্টাইল গাইডটিতে একটি সমস্যা যুক্ত করেছি ।
ড্রোগানস

1
এই উত্তরটি গ্রহণযোগ্য উত্তরের চেয়ে এটি করার জন্য "যথাযথ" উপায়টিকে আরও কার্যকরভাবে ক্যাপচার করে, যদিও উভয়ই ভাল কাজ করবে। (অবশ্যই, লিস্প ভাষাগুলির একটি দুর্দান্ত শক্তি হ'ল একই মৌলিক কাজটি করার জন্য সাধারণত বিভিন্ন উপায় রয়েছে)
জনবেকারস

2
এটি আমার কাছে কিছুটা স্পষ্ট লাগছিল এবং কিছুক্ষণের জন্য এটি মনে রাখতে আমার সমস্যা হয়েছিল, তাই আমি কিছুটা কম ভার্বোস ম্যাক্রো তৈরি করেছি
akbiggs

33

এই সমাধানটি মূল সমাধানের স্পিরিটের কাছাকাছি , তবে মার্জিনাল ক্লিনার

(defn string->integer [str & [base]]
  (Integer/parseInt str (or base 10)))

একটি অনুরূপ প্যাটার্ন যা হাতের ব্যবহারের orসাথে মিলিত হতে পারেlet

(defn string->integer [str & [base]]
  (let [base (or base 10)]
    (Integer/parseInt str base)))

এই ক্ষেত্রে আরও ভার্বোজ থাকাকালীন, যদি আপনি অন্যান্য ইনপুট মানগুলির উপর ডিফল্ট নির্ভর করতে চান তবে এটি কার্যকর হতে পারে । উদাহরণস্বরূপ, নিম্নলিখিত ফাংশনটি বিবেচনা করুন:

(defn exemplar [a & [b c]]
  (let [b (or b 5)
        c (or c (* 7 b))]
    ;; or whatever yer actual code might be...
    (println a b c)))

(exemplar 3) => 3 5 35

এই পদ্ধতির নাম হিসাবে যুক্তি (এম। গিলিয়ার সমাধান হিসাবে) কাজ করে সহজেই প্রসারিত করা যেতে পারে :

(defn exemplar [a & {:keys [b c]}]
  (let [b (or b 5)
        c (or c (* 7 b))]
    (println a b c)))

অথবা আরও বেশি ফিউশন ব্যবহার করে:

(defn exemplar [a & {:keys [b c] :or {b 5}}]
  (let [c (or c (* 7 b))]
    (println a b c)))

যদি আপনার অন্যান্য ডিফল্টের উপর নির্ভর করে আপনার ডিফল্টগুলির প্রয়োজন না হয় (অথবা সম্ভবত আপনি তা করেনও) তবে উপরে ম্যাথিউয়ের সমাধানও বিভিন্ন ভেরিয়েবলের জন্য একাধিক ডিফল্ট মানগুলির জন্য অনুমতি দেয়। এটি নিয়মিত ব্যবহার করার চেয়ে অনেক ক্লিনারor
জনবেকারস

আমি ক্লোজার নুব তাই সম্ভবত ওপেনলিয়ারার সঠিক, তবে এটি উপরে ম্যাথিউর সমাধানের একটি আকর্ষণীয় বিকল্প। আমি চূড়ান্তভাবে এটি ব্যবহার করার সিদ্ধান্ত নিয়েছি কিনা তা সম্পর্কে আমি জানতে পেরে আনন্দিত।
গ্লেনপিটারসন

orথেকে ভিন্ন :orযেহেতু orপার্থক্য জানে না nilএবং false
জিয়াংরু লিয়ান

@ জিয়াংরুলিয়ান আপনি কি বলছেন যে: বা আপনি যদি মিথ্যা পাস করেন তবে এটি ডিফল্টের পরিবর্তে মিথ্যা ব্যবহার করতে জানবে? এটির সাথে বা এটি যখন ডিফল্ট ব্যবহার করা হয় তখন মিথ্যা এবং নিজেই মিথ্যা হয়ে যায়?
দিদিয়ার এ

8

আপনি বিবেচনা করতে চাইতে পারেন এমন আরও একটি পদ্ধতি রয়েছে: আংশিক ফাংশন। এগুলি কার্যকারিতার জন্য ডিফল্ট মানগুলি নির্দিষ্ট করার জন্য একটি আরও "কার্যকরী" এবং আরও নমনীয় উপায়।

আপনি যদি অগ্রণী পরামিতি হিসাবে ডিফল্ট (গুলি) সরবরাহ করতে চান যে পরামিতি রয়েছে এমন একটি ফাংশন তৈরি করে (প্রয়োজনে) তৈরি শুরু করুন:

(defn string->integer [base str]
  (Integer/parseInt str base))

এটি করা হয়েছে কারণ ক্লোজুরের সংস্করণ partialআপনাকে ফাংশন সংজ্ঞাতে প্রদর্শিত ক্রম অনুযায়ী "ডিফল্ট" মানগুলি সরবরাহ করতে দেয়। প্যারামিটারগুলি পছন্দসই হিসাবে অর্ডার হয়ে গেলে আপনি ফাংশনটি ব্যবহার করে partialফাংশনের একটি "ডিফল্ট" সংস্করণ তৈরি করতে পারেন :

(partial string->integer 10)

এই ফাংশনটি একাধিকবার কলযোগ্য করার জন্য আপনি এটি ব্যবহার করে এটি কোনও ভারে ফেলতে পারেন def:

(def decimal (partial string->integer 10))
(decimal "10")
;10

আপনি এটি ব্যবহার করে একটি "স্থানীয় ডিফল্ট" তৈরি করতে পারেন let:

(let [hex (partial string->integer 16)]
  (* (hex "FF") (hex "AA")))
;43350

আংশিক ফাংশন পদ্ধতির অন্যদের কাছে একটি মূল সুবিধা রয়েছে: ফাংশনের গ্রাহক এখনও ফাংশন সংজ্ঞা পরিবর্তনের প্রয়োজন ছাড়াই ফাংশনের নির্মাতার চেয়ে ডিফল্ট মান কী হবে তা সিদ্ধান্ত নিতে পারে । এটি যেখানে উদাহরণস্বরূপ যেখানে আমি স্থির করেছি যে ডিফল্ট ফাংশনটি আমি চাই তা নয় examplehexdecimal

এই পদ্ধতির আরেকটি সুবিধা হ'ল আপনি ডিফল্ট ফাংশনটিকে একটি ভিন্ন নাম (দশমিক, হেক্স, ইত্যাদি) নির্ধারণ করতে পারেন যা আরও বর্ণনামূলক এবং / অথবা আলাদা স্কোপ (ভের, স্থানীয়) হতে পারে। আংশিক ফাংশনটি যদি ইচ্ছা হয় তবে উপরের কয়েকটি পদ্ধতির সাথে মিশ্রিত করা যেতে পারে:

(defn string->integer 
  ([s] (string->integer s 10))
  ([base s] (Integer/parseInt s base)))

(def hex (partial string->integer 16))

(নোট করুন এটি ব্রায়ানের উত্তর থেকে কিছুটা পৃথক কারণ প্যারামিটারগুলির ক্রম এই প্রতিক্রিয়াটির শীর্ষে প্রদত্ত কারণে বিপরীত হয়েছে)


1
এই প্রশ্নটি যা জিজ্ঞাসা করছে তা নয়; এটি আকর্ষণীয় যদিও।
জাজ

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.