2010-10-05 12 views
10

कॉमन लिस्प HyperSpecfuncall प्रविष्टिआप "लागू करें" और "funcall" कब उपयोग करते हैं?

(funcall function arg1 arg2 ...) 
== (apply function arg1 arg2 ... nil) 
== (apply function (list arg1 arg2 ...)) 

क्योंकि वे किसी भी तरह के बराबर हैं में कहते हैं, जब आप apply का प्रयोग करेंगे, और जब funcall?

उत्तर

17

आप funcall का उपयोग करना चाहिए अगर आप एक या अधिक अलग तर्क और apply अगर आप किसी सूची में अपने तर्क है

(defun passargs (&rest args) (apply #'myfun args)) 

या

(defun passargs (a b) (funcall #'myfun a b)) 
1

खैर मुझे लगता है कि अंगूठे का एक अच्छा शासन होगा हो: जब आप funcall का उपयोग नहीं कर सकते हैं तो इसका उपयोग करें: उत्तरार्द्ध स्पष्ट है लेकिन इसमें लागू होने से भी कम सामान्य है कि यह आपको उस फ़ंक्शन को कॉल करने की अनुमति नहीं देता है जिसकी तर्क संख्या केवल रनटाइम पर जानी जाती है।

बेशक

यह केवल अच्छा अभ्यास है और आप व्यवस्थित इस बदसूरत रास्ता (व्यवस्थित का उपयोग कर लागू) कर सकता है, लेकिन शायद, देखा के रूप में आपने बदसूरत रास्ते का उपयोग करते समय एक बहुत ही समान है, लेकिन क्लीनर तरीका है उपलब्ध है बहुत आम नहीं - लिस्प-वाई। समारोह के

उदाहरण funcall के बजाय लागू की जरूरत है: आप इस तरह से नक्शा लागू कर सकता है कि (map #'+ '(1 2) '(2 3)) और (map #'+ '(1 2) '(2 3) '(3 4)) दोनों काम (जो मानक समारोह के साथ मामला है) लागू (या eval, जो धोखा दे रही है) का उपयोग किए बिना ?

संपादित: के रूप में यह भी कहा गया है, यह लिखने के लिए मूर्खतापूर्ण होगा: (apply func list) के बजाय (funcall func (first list) (second list) (third list) etc.)

5

apply उपयोगी है जब तर्क सूची केवल रनटाइम पर जानी जाती है, खासकर जब तर्क सूची के रूप में गतिशील रूप से पढ़े जाते हैं। आप अभी भी funcall का उपयोग कर सकते हैं लेकिन आपको सूची से अलग-अलग तर्कों को अनपैक करना होगा, जो असुविधाजनक है। व्यक्तिगत तर्कों में गुजरकर आप applyfuncall का भी उपयोग कर सकते हैं। केवल एक चीज की आवश्यकता है कि अंतिम तर्क एक सूची होनी चाहिए:

> (funcall #'+ 1 2) 
3 
> (apply #'+ 1 2()) 
3 
संबंधित मुद्दे