2012-05-16 8 views
6

मैं अपने प्रकार में एक फ़ंक्शन रखना चाहता हूं जो वैकल्पिक तर्क लेता है। मैंने उन कार्यों में वैकल्पिक तर्कों का सफलतापूर्वक उपयोग किया है जो एक प्रकार से संबंधित नहीं हैं, हालांकि, मुझे लगता है कि यह प्रोटोकॉल और प्रकार के भीतर काम नहीं कर रहा है।डिफप्रोटोकॉल में वैकल्पिक तर्कों का उपयोग कैसे करें?

मेरे विफल रहा है परीक्षण:

Clojure 1.4.0 
user=> (defprotocol OptArg 
(func [this a & b])) 
OptArg 

user=> (deftype Imp [] OptArg 
(func [this a & b] (println a b))) 
user.Imp 

user=> (func (Imp.) 1 2) 
CompilerException java.lang.IllegalArgumentException: No single method: func of interface: user.OptArg found for function: func of protocol: OptArg, compiling:(NO_SOURCE_PATH:5) 

user=> (defn opt-arg [a & b] (println a b)) 
#'user/opt-arg 

user=> (opt-arg 1 2) 
1 (2) 
nil 
user=> (opt-arg 1) 
1 nil 
nil 
user=> 

उत्तर

8

के रूप में दिए here, प्रोटोकॉल varargs समर्थन नहीं करते। आपको प्रत्येक आवश्यक संख्या के तर्कों के लिए एक अलग विधि परिभाषित करना होगा या केवल एक तर्क के रूप में एक सूची स्वीकार करनी होगी।

+1

बहुत बहुत शुक्रिया। क्लोजर शुरुआती के रूप में मैं वास्तव में चाहता हूं कि इसके त्रुटि संदेश कुछ समझ सकें। –

+3

+1। लेकिन यह जोड़ने के लायक है कि एक अच्छा समाधान प्रोटोकॉल के बाहर एक विधि बनाना है जो * var * का समर्थन करता है, और यह फ़ंक्शन प्रोटोकॉल में उपयुक्त फ़ंक्शन को कॉल करता है – mikera

2

मैंने वैकल्पिक तर्कों के साथ प्रोटोकॉल को परिभाषित करने के लिए defprotocol+ बनाया है। विचार प्रोटोकॉल में एक निश्चित तर्क के रूप में & args बनाना और स्वचालित रूप से एक रैपर फ़ंक्शन बनाना है।

मैक्रो के लिए this gist देखें।

प्रयोग

 
(defprotocol+ IPipeline 
    (run-and-wait [this & args])) 

(defrecord+ Pipeline [] 
    IPipeline 
    (run-and-wait [this & args] 
    )) 

(run-and-wait (Pipeline.) 1 2 3 4 5) 

संबंधित मुद्दे