road - swift vxi
तेजी से भाषा में संरचना बनाम वर्ग (8)
ऐप्पल बुक से "संरचनाओं और कक्षाओं के बीच सबसे महत्वपूर्ण अंतरों में से एक यह है कि जब वे आपके कोड में चारों ओर पारित होते हैं तो संरचनाओं की हमेशा प्रतिलिपि बनाई जाती है, लेकिन कक्षाएं संदर्भ द्वारा पारित की जाती हैं।"
क्या कोई मुझे समझने दे सकता है कि इसका मतलब क्या है, मेरे लिए कक्षा और संरचना समान प्रतीत होती है।
Alreday इस बारे में बहुत कुछ लिखा है, मैं वहाँ एक समानता जोड़ना चाहता हूँ। आशा है कि इसके बाद आपको कभी भी संदेह नहीं होगा: नीचे पंक्ति: कक्षाएं संदर्भ द्वारा पारित की जाती हैं जबकि structs मूल्य से पारित होते हैं।
मान लीजिए कि आप अपने दोस्त के साथ एक Google डॉक शीट साझा कर रहे हैं। अब अगर वह उसमें कुछ भी बदलता है, तो आप यह भी देखेंगे कि आपके Google डॉक पर बदलाव का मतलब है कि आपकी प्रति भी प्रभावित होती है। यह मूल रूप से " संदर्भ द्वारा पारित " है।
लेकिन मान लें, अगर आपके पास एक मशीन है .XLS fie आपकी मशीन में सहेजी गई है। आप वह फ़ाइल अपने दोस्त को देते हैं। अब अगर वह उस फाइल में कोई बदलाव कर रहा है, तो आपकी फाइल को गड़बड़ / प्रभावित नहीं किया जाएगा क्योंकि आपकी अपनी प्रति है। यह मूल रूप से " मूल्य से पारित " है। आपके पास तेजी से खेल के मैदानों में इस समानता की जांच करने के लिए पहले से ही कई सरल कार्यक्रम हैं।
आमतौर पर (अधिकांश प्रोग्रामिंग भाषाओं में), ऑब्जेक्ट्स डेटा के ब्लॉक होते हैं जो ढेर पर संग्रहीत होते हैं, और फिर इन ब्लॉकों में एक संदर्भ (आमतौर पर एक पॉइंटर) होता है, जिसमें डेटा के इन ब्लॉक तक पहुंचने के लिए एक name
उपयोग किया जाता है। यह तंत्र उनके संदर्भों (पॉइंटर्स) के मूल्य की प्रतिलिपि बनाकर ढेर में वस्तुओं को साझा करने की अनुमति देता है। यह इंटीग्रर्स जैसे मूल डेटा प्रकारों का मामला नहीं है, और ऐसा इसलिए है क्योंकि संदर्भ बनाने के लिए आवश्यक स्मृति लगभग वस्तु के समान होती है (इस मामले में पूर्णांक मान)। इस प्रकार, वे बड़े वस्तुओं के मामले में संदर्भ के रूप में मूल्य के रूप में पारित किया जाएगा।
स्ट्रिंग और ऐरे ऑब्जेक्ट्स के साथ भी प्रदर्शन को बेहतर बनाने के लिए स्विफ्ट संरचना का उपयोग करता है।
कक्षा और संरचना दोनों कर सकते हैं:
- मूल्यों को स्टोर करने के लिए गुणों को परिभाषित करें
- कार्यक्षमता प्रदान करने के तरीकों को परिभाषित करें
- विस्तार किया
- प्रोटोकॉल के अनुरूप है
- Intialisers परिभाषित करें
- अपने चरों तक पहुंच प्रदान करने के लिए सदस्यता परिभाषित करें
केवल कक्षा ही कर सकती है:
- विरासत
- कास्टिंग टाइप करें
- Deinitialisers परिभाषित करें
- एकाधिक संदर्भों के लिए संदर्भ गिनती की अनुमति दें।
यदि आप सेब हैंडबुक में आगे देखो तो आप इस खंड को देखेंगे: "संरचनाएं और गणना मूल्य प्रकार हैं"
इस खंड में आप इसे देखेंगे:
"एचडी = संकल्प दें (चौड़ाई: 1920, ऊंचाई: 1080) var सिनेमा = एचडी यह उदाहरण निरंतर एचडी घोषित करता है और इसे संकल्प में सेट करता है उदाहरण पूर्ण एचडी वीडियो की चौड़ाई और ऊंचाई (1080 पिक्सेल चौड़े 1080 पिक्सेल ऊंचे) के साथ शुरू हुआ।
इसके बाद यह सिनेमा नामक एक चर घोषित करता है और इसे एचडी के वर्तमान मूल्य पर सेट करता है। क्योंकि संकल्प एक संरचना है, मौजूदा उदाहरण की एक प्रति बनाई गई है, और यह नई प्रतिलिपि सिनेमा को सौंपी गई है। भले ही एचडी और सिनेमा में समान चौड़ाई और ऊंचाई हो, फिर भी वे दृश्यों के पीछे दो पूरी तरह से अलग उदाहरण हैं।
इसके बाद, डिजिटल सिनेमा प्रक्षेपण (2048 पिक्सेल चौड़े और 1080 पिक्सेल ऊंचे) के लिए उपयोग किए जाने वाले थोड़ा-बड़े 2K मानक की चौड़ाई होने के लिए सिनेमा की चौड़ाई वाली संपत्ति में संशोधन किया गया है:
सिनेमा। चौड़ाई = 2048 सिनेमा की चौड़ाई संपत्ति की जांच से पता चलता है कि यह वास्तव में 2048 हो गया है:
Println ("सिनेमा अब (सिनेमा। चौड़ाई) पिक्सेल चौड़ा है") // प्रिंट्स "सिनेमा अब 2048 पिक्सल चौड़ा है हालांकि, मूल एचडी इंस्टेंस की चौड़ाई संपत्ति अभी भी पुरानी है 1 9 20 का मूल्य:
println ("एचडी अभी भी (एचडी चौड़ाई) पिक्सेल चौड़ा है") // प्रिंट "एचडी अभी भी 1920 पिक्सल चौड़ा है"
जब सिनेमा को एचडी का वर्तमान मूल्य दिया गया था, तो एचडी में संग्रहीत मूल्यों को नए सिनेमा उदाहरण में कॉपी किया गया था। अंतिम परिणाम दो पूरी तरह से अलग उदाहरण हैं, जो अभी समान संख्यात्मक मानों को शामिल करते हैं। क्योंकि वे अलग-अलग उदाहरण हैं, 2048 तक सिनेमा की चौड़ाई निर्धारित करना एचडी में संग्रहीत चौड़ाई को प्रभावित नहीं करता है। "
से उद्धरण: ऐप्पल इंक "स्विफ्ट प्रोग्रामिंग भाषा।" IBooks। https://itun.es/us/jEUH0.l
यह structs और कक्षाओं के बीच सबसे बड़ा अंतर है। संरचनाओं की प्रतिलिपि बनाई जाती है और कक्षाओं का संदर्भ दिया जाता है।
यहां class
साथ एक उदाहरण दिया गया है। ध्यान दें कि नाम कब बदला जाता है, दोनों चर द्वारा संदर्भित उदाहरण अद्यतन किया जाता है। Bob
अब Sue
, हर जगह Bob
का कभी संदर्भित किया गया था।
class SomeClass {
var name: String
init(name: String) {
self.name = name
}
}
var aClass = SomeClass(name: "Bob")
var bClass = aClass // aClass and bClass now reference the same instance!
bClass.name = "Sue"
println(aClass.name) // "Sue"
println(bClass.name) // "Sue"
और अब एक struct
साथ हम देखते हैं कि मानों की प्रतिलिपि बनाई जाती है और प्रत्येक चर यह मूल्यों का अपना सेट रखता है। जब हम Sue
को नाम देते हैं, तो संरचना में Bob
स्ट्रक्चर बदल नहीं जाता है।
struct SomeStruct {
var name: String
init(name: String) {
self.name = name
}
}
var aStruct = SomeStruct(name: "Bob")
var bStruct = aStruct // aStruct and bStruct are two structs with the same value!
bStruct.name = "Sue"
println(aStruct.name) // "Bob"
println(bStruct.name) // "Sue"
तो एक राज्य जटिल जटिल इकाई का प्रतिनिधित्व करने के लिए, एक class
भयानक है। लेकिन उन मानों के लिए जो केवल संबंधित डेटा के माप या बिट हैं, एक struct
अधिक समझ में आता है ताकि आप आसानी से उन्हें प्रतिलिपि बना सकें और उनके साथ गणना कर सकें या साइड इफेक्ट्स के डर के बिना मूल्यों को संशोधित कर सकें।
यहां एक उदाहरण दिया गया है जो संरचना और कक्षा के बीच अंतर को सटीक रूप से दिखाता है।
खेल के मैदान में लिखित कोड का स्क्रीनशॉट
struct Radio1{
var name:String
// init(name:String) {
// self.name = name
// }
}
struct Car1{
var radio:Radio1?
var model:String
}
var i1 = Car1(radio: Radio1(name:"murphy"),model:"sedan")
var i2 = i1
//since car instance i1 is a struct and
//this car has every member as struct ,
//all values are copied into i2
i2.radio?.name //murphy
i2.radio = Radio1(name: "alpha")
i2.radio?.name //alpha
i1.radio?.name //murphy
//since Radio1 was struct ,
//values were copied and thus
// changing name of instance of Radio1 in i2
//did not bring change in i1
class Radio2{
var name:String
init(name:String) {
self.name = name
}
}
struct Car2{
var radio:Radio2?
var model:String
}
var i3 = Car2(radio: Radio2(name:"murphy"),model:"sedan")
//var radioInstance = Radio2(name: "murphy")
//var i3 = Car2(radio: radioInstance,model:"sedan")
var i4 = i3
//since i3 is instance of struct
//everything is copied to i4 including reference of instance of Radio2
//because Radio2 is a class
i4.radio?.name //murphy
i4.radio?.name="alpha"
i4.radio?.name //alpha
i3.radio?.name //alpha
//since Radio2 was class,
//reference was copied and
//thus changing name of instance
//of Radio2 in i4 did bring change in i3 too
//i4.radio?.name
//i4.radio = Radio2(name: "alpha")
//i4.radio?.name
//
//i3.radio?.name
स्ट्रक्चर और कक्षाओं के बीच अंतर को समझने के लिए, हमें मूल्य और संदर्भ प्रकारों के बीच मुख्य अंतर जानने की आवश्यकता है। संरचनाएं मूल्य प्रकार हैं और इसका मतलब है कि उन पर हर परिवर्तन केवल उस मान को संशोधित करेगा, कक्षा संदर्भ प्रकार हैं और संदर्भ प्रकार में प्रत्येक परिवर्तन स्मृति या संदर्भ के उस स्थान पर आवंटित मान को संशोधित करेगा। उदाहरण के लिए:
आइए कक्षा के साथ शुरू करें, यह वर्ग उदाहरणों की तुलना करने में सक्षम होने के लिए समेकित मानता है, हम pointClassInstanceA
नामक एक उदाहरण pointClassInstanceA
और अन्य कॉल pointClassInstanceB
क्लास pointClassInstanceB
हम कक्षा ए को क्लास बी असाइन करते हैं, अब दावा कहता है कि वे वही हैं ...
class PointClass: Equatable {
var x: Double
var y: Double
init(x: Double, y: Double) {
self.x = x
self.y = y
}
static func == (lhs: PointClass, rhs: PointClass) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
}
var pointClassInstanceA = PointClass(x: 0, y: 0)
var pointClassInstanceB = pointClassInstanceA
assert(pointClassInstanceA==pointClassInstanceB)
pointClassInstanceB.x = 10
print(pointClassInstanceA.x)
//this prints 10
ठीक है, यहां क्या हुआ है अगर हमने पॉइंट क्लास इंस्टेंसबी के एक्स मान को अभी बदल दिया है तो यह pointClassInstanceA के x मान को भी बदल देता है? ठीक है, यह दिखाता है कि संदर्भ प्रकार कैसे काम करते हैं, जब हम उदाहरण ए को आवंटित करते हैं, उदाहरण बी के मान के रूप में और फिर हम उनमें से एक एक्स को संशोधित करते हैं, यह एक्स दोनों को बदल देगा क्योंकि वे एक ही संदर्भ साझा करते हैं और उसमें क्या मूल्य बदलता है संदर्भ।
चलो एक ही संरचना के साथ ही करते हैं
struct PointStruct: Equatable {
var x: Double
var y: Double
init(x: Double, y: Double) {
self.x = x
self.y = y
}
static func == (lhs: PointStruct, rhs: PointStruct) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
}
var pointStructInstanceA = PointStruct(x: 0, y: 0)
var pointStructInstanceB = pointStructInstanceA
assert(pointStructInstanceA==pointStructInstanceB)
pointStructInstanceB.x = 100
print(pointStructInstanceA.x)
//this will print 0
हमारे पास मूल रूप से हमारी कक्षा के समान संरचना है लेकिन अब आप देख सकते हैं कि जब आप pointStructInstanceA के x मान को प्रिंट करते हैं तो यह मामला नहीं बदला, और ऐसा इसलिए है क्योंकि मान प्रकार अलग-अलग काम करते हैं और उनके किसी एक उदाहरण पर प्रत्येक परिवर्तन " स्वतंत्र "और दूसरे को प्रभावित नहीं करेगा।
स्विफ्ट अधिक मूल्य प्रकारों का उपयोग करने का सुझाव देता है और आप बता सकते हैं कि उनके पुस्तकालय structs पर आधारित हैं जो कि संदर्भ प्रकारों से बचने के लिए हैं, जैसे अनजाने में मूल्य को संशोधित करना आदि। स्विफ्ट स्विफ्ट पर जाने का तरीका हैं। आशा करता हूँ की ये काम करेगा।
struct
मूल्य प्रकार हैं। इसका अर्थ यह है कि यदि आप संरचना के उदाहरण को किसी अन्य चर में कॉपी करते हैं, तो यह केवल चर के लिए कॉपी किया गया है।
मूल्य प्रकार के लिए उदाहरण
struct Resolution {
var width = 2
var height = 3
}
let hd = Resolution(width: 1920, height: 1080)
var cinema = hd //assigning struct instance to variable
println("Width of cinema instance is \(cinema.width)")//result is 1920
println("Width of hd instance is \(hd.width)")//result is 1920
cinema.width = 2048
println("Width of cinema instance is \(cinema.width)")//result is 2048
println("Width of hd instance is \(hd.width)")//result is 1920
कक्षाएं संदर्भ प्रकार हैं। इसका अर्थ यह है कि यदि आप कक्षा के एक आवृत्ति को आवंटित करते हैं, तो यह केवल उदाहरण के संदर्भ में होगा , प्रतिलिपि नहीं ।