2015-06-23 14 views
9

में मैं एप्पल डेवलपर साइट पर स्विफ्ट ट्यूटोरियल के माध्यम से किया गया है, लेकिन मैं जेनेरिक्स की अवधारणाओं समझ में नहीं आता। क्या कोई इसे सरल तरीके से समझा सकता है? उदाहरण के लिए:जेनेरिक्स स्विफ्ट 2.0

func swapTwoValues<T>(inout a: T, inout b: T) { 
    let temporaryA = a 
    a = b 
    b = temporaryA 
} 
+0

शानदार सवाल, यदि आप अपने प्रश्न को पूरा करते हैं तो आपको इस प्रश्न का उत्तर चुनने पर विचार करना चाहिए! यह आपकी पोस्ट की गुणवत्ता में सुधार करता है और इस प्रकार समुदाय को लाभ देता है। –

उत्तर

11

उदाहरण आप दे दी है में जेनरिक का उपयोग कर के बिना के लिए कई कार्यों लेखन के एक समारोह लिखते हैं, आप हर प्रकार आप चाहते थे के लिए swapTwoValues ओवरलोड होगा अदला बदली करना। उदाहरण के लिए:

func swapTwoValues(inout a: Int, inout b: Int) { 
    let temp = a 
    a = b 
    b = temp 
} 

func swapTwoValues(inout a: String, inout b: String) { 
    let temp = a 
    a = b 
    b = temp 
} 

// Many more swapTwoValues functions... 

उपरोक्त कार्यों के बीच अलग-अलग चीज वह है जो वे स्वीकार करते हैं; प्रत्येक के अंदर कोड बिल्कुल वही है। इसलिए, एक जेनेरिक फ़ंक्शन लिखना बेहतर है जो किसी भी प्रकार का समय ले सकता है।

यह ध्यान रखना महत्वपूर्ण है कि आप T को Any के साथ प्रतिस्थापित नहीं कर सकते हैं। इसकी कोई गारंटी नहीं a होगा और b एक ही प्रकार हो सकता है - आप एक Int और एक String स्वैप नहीं कर सकता है, उदाहरण के लिए।

1

अनिवार्य रूप से, इसका मतलब यह है कि यह विशिष्ट प्रकार नहीं है। आप T का उपयोग करें और बस के बजाय प्रत्येक प्रकार Int, Double, Float, String आदि

4

अपने उदाहरण टी में एक प्रकार का प्रतिनिधित्व करता है। और एक बार सेट उस प्रकार के पूरे समारोह के लिए संगत है।

func swapTwoValues<T>(inout a: T, inout b: T) { 
    let temporaryA = a 
    a = b 
    b = temporaryA 
} 

तो टी पैरामीटर के मामले में एक इंट है, तो यह भी पैरामीटर ख के मामले में एक इंट होना होगा। के रूप में समारोह के इस प्रयोग में प्रदर्शन:

var valueA = 2 
var valueB = 4 
swapTwoValues(&valueA, b: &valueB) 

valueA // 4 
valueB // 2 

हम एक डबल के लिए उदाहरण के लिए एक इंट या यहां तक ​​कि एक इंट के लिए एक स्ट्रिंग स्वैप नहीं कर सकता है, लेकिन जब तक प्रकार एक ही हैं तो यह सामान्य विधि किसी भी ले जाएगा टाइप करें, क्योंकि यह अन्य सभी मामलों में अनियंत्रित है।

var valueA = "Hello" 
var valueB = "Swift" 
swapTwoValues(&valueA, b: &valueB) 

valueA // "Swift" 
valueB // "Hello" 

इसका मतलब यह नहीं है कि कई प्रकार सामान्य कार्यों से बाहर किए गए हैं। आप बस विभिन्न प्रकार का प्रतिनिधित्व करने के लिए एक अलग पत्र सौंपने होंगे (प्रयुक्त पत्र अप्रासंगिक है, टी बस प्रयोग किया जाता है, क्योंकि यह प्रकार के पहले अक्षर है, लेकिन उदाहरण के लिए कोई कारण नहीं है यह क्यू के साथ बदल नहीं किया जा सका है, या किसी अन्य पत्र):

func swapTwoValues<T,S>(inout a: T, inout b: T, inout c: S, inout d: S) { 
    let temporaryA = a 
    a = b 
    b = temporaryA 

    let temporaryC = c 
    c = d 
    d = temporaryC 
} 

var valueA = 2 
var valueB = 4 

var valueC = "Hello" 
var valueD = "Swift" 
swapTwoValues(&valueA, b: &valueB, c:&valueC, d:&valueD) 

valueA // 4 
valueB // 2 

valueC // "Swift" 
valueD // "Hello" 

नोट: हम अभी भी एक एस के लिए एक टी स्वैप नहीं कर सकते क्योंकि स्विफ्ट एक जोरदार टाइप किया भाषा है और हम कोई आश्वासन वे एक ही हैं।

यह और अधिक दिलचस्प हो जाता है जब प्रोटोकॉल सामान्य प्रकार विवश करने के लिए शामिल हैं। यहाँ मैं UnsignedIntegerType के साथ ऐसा:

func swapTwoValues<T: UnsignedIntegerType>(inout a: T, inout b: T) { 
    let temporaryA = a 
    a = b 
    b = temporaryA 
} 

var valueA:UInt = 10 
var valueB:UInt = 11 

swapTwoValues(&valueA, b: &valueB) 

ऐसे uint, UInt8, UInt32, आदि के रूप में अब केवल प्रकार स्वीकार्य हैं और अन्य सभी मान को अस्वीकार कर दिया और एक त्रुटि बनाने की जाएगी।

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

हम आगे जाकर प्रकार एक सामान्य संग्रह के भीतर निहित निर्धारित करने के लिए where कीवर्ड का उपयोग कर सकते हैं:

func swapTwoValues<T: CollectionType where T.Generator.Element: UnsignedIntegerType>(inout a: T, inout b: T) { 
    let temporaryA = a 
    a = b 
    b = temporaryA 
} 

var valueA:[UInt] = [10,12,4] 
var valueB:[UInt] = [11,45,67] 

swapTwoValues(&valueA, b: &valueB) 

valueA // [11, 45, 67] 
valueB // [10, 12, 4] 

या जांच की तरह बातें करते हैं कि एक दूसरे प्रकार एक संग्रह में तत्वों के प्रकार के बराबर है == का उपयोग कर:

func swapTwoValues<T: CollectionType, S where S == T.Generator.Element>(inout a: T, inout b: T, inout c: S, inout d: S) { 
    let temporaryA = a 
    a = b 
    b = temporaryA 

    let temporaryC = c 
    c = d 
    d = temporaryC 
} 

अतिरिक्त पठन: हालात और भी अधिक के साथ protocol extensions in Swift 2 क्योंकि अब सामान्य कार्यों प्रकार के तरीकों की विशेषताओं पर ले जा सकते हैं, जो उन्हें अब तक बनाता मीटर दिलचस्प हो अयस्क खोजने योग्य

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