2016-06-10 8 views
7

मैं सिर्फ बाहर पाया है कि स्विफ्ट के private पहुँच संशोधक फ़ाइल स्तर, के रूप में के तहत "प्रवेश स्तर" docs में निर्धारित है:स्विफ्ट एक ही फ़ाइल में निजी चर के उपयोग की अनुमति क्यों देता है?

स्विफ्ट में निजी उपयोग, सबसे अन्य भाषाओं में निजी उपयोग से अलग है के रूप में यह scoped है संलग्न घोषणा के बजाय संलग्न स्रोत फ़ाइल में। इसका अर्थ यह है कि एक प्रकार किसी भी निजी संस्थाओं को एक्सेस कर सकता है जो उसी स्रोत फ़ाइल में स्वयं परिभाषित होते हैं, लेकिन एक एक्सटेंशन उस प्रकार के निजी सदस्यों तक नहीं पहुंच सकता है यदि इसे एक अलग स्रोत फ़ाइल में परिभाषित किया गया हो।

तो इसका मतलब यह है जब प्रकार एक ही फाइल में हैं निम्नलिखित कोड संकलन होगा:

class FirstType { 
    private var privateProperty: String = "" 
} 

class SecondType { 
    private let firstType = FirstType() 

    func messWithFirstType() { 
     firstType.privateProperty = "" // this compiles and works! 
    } 
} 

जहां तक ​​मैं देख सकता हूँ, यह पूरी तरह से टूट जाता है encapsulation। दूसरी तरफ, पठनीयता के लिए एक ही फाइल में एक साथ समूहित कुछ संबंधित प्रकार होना अच्छा हो सकता है, खासकर यदि संबंधित प्रकार छोटे हैं, जैसे कि enums।

निजी एक्सटेंशन एक अपवाद है क्योंकि वे एक ही प्रकार फ़ाइल का मतलब है का विस्तार कर रहे हैं। और निजी एक्सटेंशन कुछ nice things लाते हैं।

वहाँ किसी भी अन्य कारण के अलावा, निजी एक्सटेंशन को सुविधाजनक बनाने फ़ाइल गुंजाइश private पहुँच संशोधक स्विफ्ट में होने के लिए से कर रहे हैं?

+2

मैं इतना तेज़ नहीं कहूंगा कि यह encapsulation तोड़ता है। यदि आपके पास दो कक्षाएं हैं जो एक-दूसरे से संबंधित नहीं हैं (और एक दूसरे के आंतरिक के बारे में नहीं जानी चाहिए) तो शायद वे एक ही स्रोत फ़ाइल में नहीं होनी चाहिए। –

+4

संबंधित: [एक्सेस कंट्रोल और संरक्षित] (https://developer.apple.com/swift/blog/?id=11) स्विफ्ट ब्लॉग में। –

+0

@CraigOtis किस प्रकार को "संबंधित" के रूप में परिभाषित किया जा सकता है ताकि वे एक दूसरे के आंतरिक के साथ गड़बड़ कर सकें? दो अलग-अलग वर्गों को एक-दूसरे की निजी घटकों की अवधि के बारे में नहीं पता होना चाहिए। मैं अपने स्वयं के स्रोत फाइलों में, यहां तक ​​कि छोटे लोगों को रखने के लिए झुका रहा हूं। –

उत्तर

7

यह मुझे स्पष्ट नहीं है कि private मूल रूप से फ़ाइलों के संबंध में क्यों लागू किया गया था, लेकिन बाकी ने आश्वस्त किया कि स्विफ्ट लोगों को पता है कि यह private का एकमात्र संभव अर्थ नहीं है और यह कुछ उद्देश्यों के लिए आदर्श नहीं है, और इसे बदलने के लिए काम कर रहे हैं। वहां पहले से ही एक proposal मेज, स्विफ्ट 3 के लिए स्वीकार किए जाते हैं पर, कि वर्तमान privatefileprivate में बदल जाते हैं और उस प्रकार के बजाय फ़ाइल के दायरे वाला हो जाएगा private के एक नए स्तर जोड़ना होगा है। आप उम्मीद कर सकते हैं कि यह निकट भविष्य में स्विफ्ट 3 का हिस्सा बन जाएगा।

+0

असल में, आप पार्टी के लिए बस देर हो चुकी हैं। आप [चर्चा] (http://thread.gmane.org/gmane.comp.lang.swift.evolution/9334) पढ़ने के आनंद ले सकते हैं क्योंकि यह सामने आया है। – matt

+2

स्विफ्ट 3.0 में किया गया: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AccessControl.html#//apple_ref/doc/uid/TP40014097-CH41-ID3 – KarimIhab

1

जब आप कुछ भी है कि "अजीब" स्विफ्ट, समय जवाब "ऑब्जेक्टिव-सी की वजह से" है के अधिकांश में लगता है के बारे में चिंता।

  1. private: केवल वर्ग है जिसमें यह परिभाषित किया गया है के लिए सुलभ

    कुछ परिप्रेक्ष्य के लिए, मैं 3 पहुंच का स्तर आम कई आधुनिक प्रोग्रामिंग भाषाओं पर विचार करें।

  2. protected: वर्ग जिसमें यह परिभाषित किया गया है और उसके उपवर्गों ही सुलभ।
  3. public: किसी भी बाहरी कार्यक्रम के लिए सुलभ।

के एक कदम और आगे वापस सी सी की दुनिया के लिए ले, चलो नहीं एक OOP भाषा जा रहा है कोई पहुँच संशोधक है। हालांकि, हकीकत में, यह एक निजी/सार्वजनिक प्रणाली होने के करीब है। यदि आप अन्य कार्यक्रमों को अपने प्रतीकों (कार्यों, मैक्रोज़, डेटा प्रकार इत्यादि) को जानना चाहते हैं, तो आप उन्हें अपने शीर्षलेख (.h) फ़ाइल में परिभाषित करते हैं। यदि नहीं, तो आप उन्हें अपने स्रोत (.c) फ़ाइल या एक निजी शीर्षलेख फ़ाइल में परिभाषित करते हैं।जो भी कार्यक्रम अपने प्रतीक में रुचि इसी हेडर फाइल में शामिल होंगे:

#include "foo.h" 

यह #include एक संकलक की मदद से नकल & पेस्ट से अधिक नहीं है। संकलक foo.h में सभी प्रतीकों की प्रतिलिपि बनाता है और उन्हें अपनी स्रोत फ़ाइल में पुन: प्राप्त करता है।

चूंकि उद्देश्य-सी सी का सख्त सुपरसेट है, इसलिए प्रत्येक मान्य सी प्रोग्राम भी वैध उद्देश्य-सी प्रोग्राम है। ऑब्जेक्टिव-सी इस परंपरा जारी है: हेडर फाइल में अपनी सार्वजनिक तरीकों की घोषणा, कार्यान्वयन फाइल करने के लिए निजी तरीकों घोषणा रखें:

// ------------------------------------------ 
// MyClass.h 
// ------------------------------------------ 
@interface MyClass: NSObject 
- (void) publicMethod; 
@end 


// ------------------------------------------ 
// MyClass.m 
// ------------------------------------------ 
#import "MyClass.h" 

// Declare your private methods here. 
// You can move this to a separate file, i.e. MyClass+Private.h if you want 
@interface MyClass() 
- (void) privateMethod; 
@end 

@implementation MyClas  
- (void) publicMethod() { ... } 
- (void) privateMethod() { ... } 
@end 

तो नज़र में, ऑब्जेक्टिव-सी सार्वजनिक/निजी घोषणाओं के सी प्रणाली के वारिस लगता है। हालांकि, उद्देश्य-सी एक बहुत ही गतिशील भाषा है। आप कक्षा, निजी या सार्वजनिक के सभी तरीकों के लिए अपने रनटाइम से पूछ सकते हैं। उद्देश्य-सी में एक्सेस कंट्रोल "इस विधि को आपके लिए सीमित है" के बजाय "प्रलेखन में जो कुछ मैं आपको बताता हूं उसका उपयोग करें" के बारे में अधिक है।

यह एक विरोधाभास है: आप उद्देश्य-सी में protected कैसे कार्यान्वित करते हैं? इसके लिए इसका कोई अच्छा जवाब नहीं है। एक आम पैटर्न एक अलग घोषणा फ़ाइल में सभी सुरक्षित तरीकों को स्थानांतरित करने और मुख्य वर्ग और उपवर्ग के कार्यान्वयन में उन्हें आयात करने के लिए है:

// ------------------------------------------ 
// MyClass+Protected.h 
// ------------------------------------------ 
@interface MyClass (Protected) 
- (void) protectedMethod; 
@end 

// ------------------------------------------ 
// MySubClass.m 
// ------------------------------------------ 
#import "MyClass+Protected.h" 
... 

स्विफ्ट बस, उस परंपरा पर किया जाता है बेहतर या बदतर के लिए। स्विफ्ट 3 में इसे बदलने के लिए an accepted proposal है। यदि कुछ भी हो, तो क्रिस लैटनर और स्विफ्ट टीम ने अतीत और सी की विरासत के लिए थोड़ा सा संबंध दिखाया है। आप ++ और सी-शैली को हटाने के साथ स्विफ्ट 2.2 में इसका सबूत देख सकते हैं। for loops।

+0

अपना उत्तर प्रशंसा करें। मुझे संदेह है कि यह व्यवहार किसी भी तरह उद्देश्य-सी दुनिया में निहित है। लेकिन यह अभी भी मुझे स्पष्ट नहीं है कि यह वास्तव में क्यों किया गया था। –

+0

कुछ ऐतिहासिक संदर्भ: ऐप्पल ने क्लेंग कंपाइलर पर अपने प्रभावशाली कार्यों के कारण क्रिस लैटनर को काम पर रखा। ऐप्पल में उनकी पहली परियोजना शायद क्लेंग में ओबीजेसी समर्थन जोड़ सकती थी। रास्ते में, या तो वह या कुछ वरिष्ठ ऐप्पल कर्मचारी ने एक नई नई भाषा के विचार का प्रस्ताव दिया जिसे हम अब स्विफ्ट के रूप में जानते हैं। ओबीजेसी में उनकी गहरी भागीदारी थी। और एक बार जब आप एक निश्चित तरीके से प्रशिक्षित हो जाते हैं, तो आप अपने अनुभव का पालन करते हैं। –

+0

बेशक यह उससे अधिक जटिल हो सकता है, जैसे ऐप्पल के कुछ वरिष्ठ इंजीनियरों को ओबीजेसी में इतना उपयोग किया जाता है और ओबीजेसी-शैली एक्सेस संशोधक का उपयोग करने के लिए स्विफ्ट टीम पर दबाव डाला जाता है। मुझे खुशी है कि यह –

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

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