स्विफ्ट संदर्भों में _ अंडरस्कोर प्रतिनिधि क्या है?


144

Apple के डॉक्स के संदर्भ खंड में इस प्रकार की बहुत सी घटनाएं हैं:

func runAction(_action: SKAction!)

इस का उद्देश्य-सी 'समकक्ष' है:

- (void)runAction:(SKAction *)action

यह मुझे चौंकाता है कि शायद यह महत्वपूर्ण है कि (स्विफ्ट संदर्भ में) अंडरस्कोर के बाद एक जगह है और इटैलिक में "एक्शन" लिखा गया है।

लेकिन मैं यह पता लगाने की कोशिश नहीं कर सकता कि यह क्या संदेश दे रहा है। तो शायद सवाल यह है ... क्या संदर्भों में इस्तेमाल किए गए सम्मेलनों के लिए एक संदर्भ है?

- यहाँ वह पृष्ठ है जो मैं इस संदर्भ में अंडरस्कोर उपयोग के संदर्भ में बता रहा हूं: https://developer.apple.com/documentation/spritekit/sknode#//apple_ref/occ/instm/SKNode/rnAction

अपडेट करें

स्विफ्ट 3 ने कुछ बदलाव किए हैं कि कैसे फ़ंक्शन / विधि पैरामीटर नाम और तर्क लेबल का उपयोग किया जाता है और नाम दिया जाता है। इस प्रश्न और इसके उत्तर पर इसके प्रभाव हैं। @ रिक्टर कार्यों में _underscores के बारे में एक अलग सवाल का जवाब देने का एक अद्भुत काम करता है जो इसे बहुत साफ करता है, यहां: मुझे स्विफ्ट में अंडरस्कोर की आवश्यकता क्यों है?


3
[Underscore.js] के साथ टैग की गईं ??
मार्टिन आर

3
प्रलेखन चर नामों के लिए इटैलिक का उपयोग करने के गणितीय सम्मेलन का पालन कर रहा है। उदाहरण के लिए: sin rob a + cos² a = 1.
rob mayoff

जवाबों:


116

दोनों उत्तर सही थे लेकिन मैं थोड़ा और स्पष्ट करना चाहता हूं।

_तरीकों के लिए बाहरी पैरामीटर नाम व्यवहार को संशोधित करने के लिए उपयोग किया जाता है ।

में स्थानीय और तरीके के लिए बाहरी पैरामीटर नाम प्रलेखन की धारा है, यह कहते हैं:

स्विफ्ट पहले पैरामीटर नाम को डिफ़ॉल्ट रूप से स्थानीय पैरामीटर नाम में एक विधि देता है, और दूसरे और बाद के पैरामीटर को डिफ़ॉल्ट रूप से स्थानीय और बाहरी दोनों पैरामीटर नाम देता है।

दूसरी ओर, डिफ़ॉल्ट रूप से फ़ंक्शन में बाहरी पैरामीटर नाम नहीं होते हैं।

उदाहरण के लिए, हमारे पास यह foo()विधि कक्षा में परिभाषित है Bar:

class Bar{
    func foo(s1: String, s2: String) -> String {
        return s1 + s2;
    }
}

जब आप कॉल करते हैं foo(), तो इसे कहा जाता है bar.foo("Hello", s2: "World")

लेकिन , आप का उपयोग करके इस व्यवहार को ओवरराइड कर सकते हैं _के सामने s2जहां यह घोषित किया है।

func foo(s1: String, _ s2: String) -> String{
    return s1 + s2;
}

फिर, जब आप कॉल करते हैं foo, तो इसे bar.foo("Hello", "World")दूसरे पैरामीटर के नाम के बिना बस बुलाया जा सकता है ।

आपके मामले में वापस, runActionएक विधि है क्योंकि यह प्रकार से जुड़ा हुआ है SKNode, जाहिर है। इस प्रकार, _पहले पैरामीटर को डालने से actionआप runActionबाहरी नाम के बिना कॉल कर सकते हैं।

स्विफ्ट 2.0 के लिए अपडेट

समारोह और विधि अब स्थानीय और बाहरी तर्क नाम घोषणा के संदर्भ में उसी तरह काम करते हैं ।

डिफ़ॉल्ट रूप से बाहरी पैरामीटर नाम का उपयोग करके फ़ंक्शन को 2 पैरामीटर से शुरू किया जाता है। यह नियम केवल शुद्ध स्विफ्ट कोड पर लागू होता है।

इसलिए, _एक फ़ंक्शन के सामने एक प्रदान करके , कॉल करने वाले को बाहरी पैरामीटर नाम निर्दिष्ट नहीं करना होगा, जैसे आप एक विधि के लिए क्या करेंगे ।


9
उलझन में, अगर _दूसरे पैरामीटर से पहले लिखना, आपका उत्तर स्पष्ट रूप से पर्याप्त है; क्या होगा अगर func runAction(_action: SKAction!), _पहले पैरामीटर से पहले है या यदि आप निम्नलिखित कोड लिखते हैं तो func foo(_ s1: String) { // your code }Xcode आपको चेतावनी देगा, लेकिन func bringSubviewToFront(_ view: UIView)संदर्भ में बहुत कुछ कोड है , क्यों?
विल झांग

10
इसलिए मूल रूप से, यह बिना किसी कारण के ऐसा करता है और हर किसी को भ्रमित करता है। बहुत बढ़िया।
बॉटबोट

2
अंडरस्कोर को 'वाइल्डकार्ड पैटर्न' डेवलपर.
apple.com/library/ios/documentation/Swift/Conceptual/…

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

4
यह ध्यान रखना महत्वपूर्ण है कि स्विफ्ट 3.0 चीजों को बदलता है। सभी लेबल आवश्यक हैं, जब तक कि आप अन्यथा निर्दिष्ट न करें। तो -पहले पैरामीटर से पहले अब बाहरी नहीं है। उदाहरण के लिए: override func viewWillAppear(_ animated: Bool)सिग्नल कि कॉलर (ऑब्जेक्टिव-सी कोड) एक पैरामीटर लेबल का उपयोग नहीं करेगा
श्री टी

85

अंडरस्कोर एक सामान्य टोकन है जिसका उपयोग एक अस्वीकृत मूल्य को इंगित करने के लिए किया जाता है।

इस विशिष्ट मामले में, इसका मतलब है कि फ़ंक्शन को runAction(argument)इसके बजाय लागू किया जाएगाrunAction(action:argument)

अन्य संदर्भों में इसके समान अर्थ हैं, जैसे:

for _ in 0..<5 { ... }

इसका मतलब है कि हम केवल 5 बार ब्लॉक निष्पादित करना चाहते हैं और हम ब्लॉक के भीतर इंडेक्स की परवाह नहीं करते हैं।

इस सन्दर्भ में:

let (result, _) = someFunctionThatReturnsATuple()

इसका मतलब है कि हमें इस बात की परवाह नहीं है कि टपल का दूसरा तत्व क्या है, केवल पहला।


तो इस मामले में तर्क (एक कार्रवाई) एक विकल्प है?
भ्रमित

1
नहीं, यह बाहरी पैरामीटर नाम का कारण बनता है (क्रिया :) इस मामले में, खाली होने के लिए, इस प्रकार छोड़ा गया। तर्क अभी भी आवश्यक है, यह सिर्फ कार्रवाई के साथ टैग नहीं किया गया है:
डेविड बेरी

4
असली उत्तर @ dasblinkenlight के उत्तर और मेरा का संयोजन है। वह इस विशिष्ट मामले को अधिक सटीक रूप से संबोधित करता है, जबकि मेरा व्यापक प्रश्न को संबोधित करता है, _ का क्या अर्थ है?
डेविड बेरी

4
आप उन्हें इस तरह से अधिक पठनीय बनाने के लिए बहुत बड़ी संख्या के लिए त्याग चिह्न का भी उपयोग कर सकते हैंlet pi = 3.141_592_653_59
एसएमपी

मनोरंजक रूप से, आप इसे बहुत बड़ी संख्या में कम पठनीय बनाने के लिए भी उपयोग कर सकते हैं, जैसेlet pi = 3.1_4_15_92___63
डेविड बेरी

15

स्विफ्ट 3 के बाद से डिफ़ॉल्ट रूप से सभी तर्क लेबल आवश्यक हैं

आप आईडीई को तर्क लेबल छिपाने के लिए बाध्य कर सकते हैं _

func foo(a: String) {
}

func foo2(_ a: String) {
}

बुलाया foo(a: "abc")औरfoo2("abc")

नोट: यह प्रयोग किया जा सकता है केवल जब aहै (बाह्य) तर्क लेबल और (आंतरिक) चर नाम एक ही समय में। यह समतुल्य है - func foo(a a: String)स्वीकार नहीं करेगा _

Apple इसका उपयोग क्यों कर रहा है?

आप देख सकते हैं कि Apple इसे पूरे एपीआई में उपयोग कर रहा है। Apple के पुस्तकालय अभी भी ऑब्जेक्टिव-सी में लिखे गए हैं (यदि नहीं, तो वे वैसे ही फ़ंक्शन नाम साझा करते हैं, जो ऑब्जेक्टिव-सी सिंटैक्स के लिए डिज़ाइन किए गए थे)

जैसे कार्यों applicationWillResignActive(_ application: UIApplication)के लिए होता है अनावश्यक पैरामीटर नाम applicationके बाद से वहाँ पहले से ही है, आवेदन यह समारोह के नाम पर।

आपका उदाहरण

func runAction(_ action: SKAction!)इसे बिना_ मार्क के कहा जाएगा runAction(action:)। पैरामीटर नाम निरर्थकaction होगा क्योंकि फ़ंक्शन नाम में पहले से ही एक है। यही उद्देश्य है और यह क्यों है।


13

पैरामीटर घोषणा के सामने एक पहचानकर्ता एक बाहरी पैरामीटर नाम को परिभाषित करता है । यह वह नाम है जिसे फ़ंक्शन को कॉल करते समय कॉलर द्वारा प्रदान किया जाना चाहिए:

func someFunction(externalParameterName localParameterName: Int)

स्विफ्ट आपके द्वारा परिभाषित किसी भी डिफ़ॉल्ट पैरामीटर के लिए एक स्वचालित बाहरी नाम प्रदान करता है, यदि आप स्वयं एक बाहरी नाम प्रदान नहीं करते हैं। बाहरी पैरामीटर नाम के लिए एक अंडरस्कोर का उपयोग इस व्यवहार से बाहर निकलता है:

_जब आप पैरामीटर को परिभाषित करते हैं तो एक स्पष्ट बाहरी नाम के बजाय एक अंडरस्कोर ( ) लिखकर आप इस व्यवहार से बाहर निकल सकते हैं ।

आप पर अनुभाग में इस व्यवहार के बारे में अधिक पढ़ सकते हैं डिफ़ॉल्ट मान के साथ पैरामीटर के लिए बाहरी नाम यहाँ


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

4
@Confused मेरी समझ यह है कि SKडिज़ाइनर आपको actionदो बार लिखना नहीं चाहते , क्योंकि "एक्शन" पहले से ही फ़ंक्शन के नाम का एक हिस्सा है। दूसरे शब्दों में, वे नहीं चाहते कि आप लिखें sprite.runAction(action:moveGroundSpritesForever)। बाहरी पैरामीटर नामों का उद्देश्य आपके कोड को "एक वाक्य की तरह पढ़ना" बनाना था; actionदो बार उपयोग करने से उस उद्देश्य की हार होगी।
दासब्लिंकलाइटलाइट

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

1
हालांकि अंडरस्कोर का उपयोग किसी भी तरह से इन बाहरी पैरामीटर नामों को डिफ़ॉल्ट मान के साथ परिभाषित मापदंडों के लिए किया जा सकता है ... बस यह नहीं देखा कि यह कैसे किया जाता है, अभी तक। ढूंढते रह जाओगे।
उलझन

इसलिए ... संक्षेप में, यह केवल नामित मापदंडों और क्रमिक मापदंडों के बीच स्विच करता है, इसलिए आप आसानी से foo.bar(param: 'fiddle') और foo.bar('fiddle') नोट के बीच टॉगल कर सकते हैं : केवल एक तर्क के साथ यह वास्तव में स्पष्ट नहीं होता है ... लेकिन कई तर्कों के साथ यह बहुत प्रासंगिक हो जाता है: foo.bar(param1: 'fiddle', param2: 'dee') बनाम foo.bar('fiddle','dee')
jrypkahauer

10

मुझे लगता है कि यह स्विफ्ट में एक सम्मेलन को बल देता है, जो इसे उद्देश्य-सी के करीब पढ़ता है, जो कोको सम्मेलनों से बेहतर मेल खाता है। Objc में आप (बाह्य रूप से) अपने पहले पैरामीटर को नाम नहीं देते हैं। इसके बजाय, सम्मेलन द्वारा आप आमतौर पर विधि नाम के उत्तरार्द्ध में बाहरी नाम को इस तरह शामिल करते हैं:

- (void)myFancyMethodWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName;

[someInstance myFancyMethodWithFirstName:@"John" lastName:@"Doe"];

स्विफ्ट आपी कॉल करने के लिए objc के अनुरूप है जिसे आप पहले पैरामीटर के बाहरी पैरामीटर नाम को दबाना चाहेंगे।

func myFancyMethodWithFirstName(_ firstName:String, lastName:String);

someInstance.myFancyMethodWithFirstName("John", lastName:"Doe")

2
मुझे यह स्पष्टीकरण पसंद है। पहले ओब्ज-सी सीखे, आप चीजों को साफ कर चुके हैं। यह स्विफ्ट में विधि के नामकरण के महत्व पर भी प्रकाश डालता है, अर्थात् विधि नाम के उत्तरार्द्ध को पहले तर्क का वर्णन करना चाहिए, जैसा कि आम तौर पर ओबज-सी में होता है। अच्छी चीज़।
rrrrrraul

5

दरअसल, Apple के डॉक्स में एक विधि और विधि घोषणा को परिभाषित करने के लिए उपयोग किए जाने वाले वास्तविक कोड के बीच अंतर है। आइए UIControl का उपयोग करें - addTarget: कार्रवाई: forControlEvents: उदाहरण के लिए विधि, वास्तविक कोड: यहां छवि विवरण दर्ज करें

लेकिन डॉक्स में, यह इस तरह दिखाई देता है (लक्ष्य से पहले नोटिस _): यहां छवि विवरण दर्ज करें

वास्तविक कोड में, _ का उपयोग दूसरे या बाद के पैरामीटर के बाहरी नाम को प्रकट करने के लिए किया जाता है जब कोई विधि कहा जाता है, जबकि डॉक्स में, _ किसी पैरामीटर के स्थानीय नाम से पहले यह इंगित करता है कि जब आप किसी विधि या फ़ंक्शन को कॉल करते हैं, तो आपको एक प्रदान नहीं करना चाहिए बाहरी नाम।

जब कोई फ़ंक्शन डिफ़ॉल्ट रूप से कॉल किया जाता है, तो कोई बाहरी नाम नहीं होता है जब तक कि आप अपना स्वयं का या बिना (व्हॉट्सएप के) किसी पैरामीटर का स्थानीय नाम नहीं जोड़ते हैं, उदाहरण के लिए, यह है कि हम डिस्पैच_आफ्टर का उपयोग करते हैं : यहां छवि विवरण दर्ज करें

और डॉक्स में, यह इस तरह दिखाई देता है (नोटिस तीन _): यहां छवि विवरण दर्ज करें

फ़ंक्शन की घोषणा का सम्मेलन उसी तरह है जैसे मैंने विधि के लिए वर्णित किया है।


1

बस और अधिक नेत्रहीन।

यहां छवि विवरण दर्ज करें

जैसा कि आप देख सकते हैं _बस स्थानीय पैरामीटर नाम को छोड़ दें या नहीं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.