Swift3 में फ़ाइलपाइप और निजी के बीच अंतर करने के लिए एक अच्छा उदाहरण क्या है


142

यह लेख नए एक्सेस स्पेसर्स को समझने में मददगार रहा है Swift 3। यह fileprivateऔर के विभिन्न प्रयोगों के कुछ उदाहरण भी देता है private

मेरा सवाल यह है fileprivateकि एक ऐसे फंक्शन का उपयोग नहीं किया जा रहा है जो केवल इस फाइल में उपयोग होने वाला है private?

जवाबों:


282

fileprivateअब जो privateपहले स्विफ्ट रिलीज़ में हुआ करता था: उसी स्रोत फ़ाइल से पहुँचा जा सकता है। एक घोषणा के रूप में चिह्नित किया privateजा सकता है जो अब केवल लेक्सिकल दायरे में पहुँचा जा सकता privateहै fileprivate

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

उदाहरण (सभी एक स्रोत फ़ाइल में):

class A {
    private func foo() {}
    fileprivate func bar() {}

    func baz() {
        foo()
        bar()
    }
}

extension A {
    func test() {
        foo() // Swift 3: error: use of unresolved identifier 'foo'
              // Swift 4: no error because extension is in same source file
        bar()
    }
}

let a = A()
a.foo() // error: 'foo' is inaccessible due to 'private' protection level
a.bar()
  • निजी fooपद्धति केवल class A { ... }परिभाषा के दायरे में ही सुलभ है । यह एक एक्सटेंशन से टाइप तक भी नहीं पहुँचा जा सकता है (स्विफ्ट 3 में, स्विफ्ट 4 में बदलाव के लिए नीचे दूसरा नोट देखें)।

  • फ़ाइल-निजी barविधि समान स्रोत फ़ाइल से सुलभ है।

टिप्पणियाँ:

  1. प्रस्ताव SE-0159 - फिक्स प्राइवेट एक्सेस लेवल्स ने स्विफ्ट 4 में स्विफ्ट 2 शब्दार्थ को वापस लाने का सुझाव दिया। स्विफ्ट-इवोल्यूशन मेलिंग सूची पर एक लंबी और विवादास्पद चर्चा के बाद, प्रस्ताव को अस्वीकार कर दिया गया ।

  2. प्रस्ताव SE-0169 - निजी घोषणाओं के बीच बातचीत में सुधार और एक्सटेंशनprivate एक ही प्रकार के एक्सटेंशन के लिए सुलभ के भीतर घोषणाएं करने का सुझाव देता है यदि एक्सटेंशन उसी स्रोत फ़ाइल में परिभाषित किया गया है इस प्रस्ताव को स्विफ्ट 4 में स्वीकार किया गया और लागू किया गया।


2
यदि आप स्विफ्ट 2 से 3 में कोड को स्वचालित रूप से परिवर्तित कर रहे हैं, तो Xcode चालू privateहो जाएगा fileprivate। हालांकि, अगर आप हाथ से यह कर के लक्जरी है, तो आप अक्सर छोड़ने से फायदा हो सकता privateके रूप में private, सब अच्छा ... अगर यह संकलित करता है।
दान रोसेनस्टार्क

@DanielLarsson: अपने सुझावों को संपादित करें: दोनों टिप्पणियाँ foo()कॉल पर लागू होती हैं ।
मार्टिन आर

82

मैं सिर्फ निजी , फ़ाइलपाइप , ओपन और पब्लिक के बारे में एक चित्र बनाता हूं

आशा है कि यह जल्दी से आपकी मदद कर सकता है, पाठ विवरण के लिए कृपया मार्टिन आर के जवाब को देखें

[अद्यतन 4 स्विफ्ट]

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


9
बाहर देखें, fileprivateएक्सटेंशन से जुड़ा नहीं है , लेकिन फ़ाइल में (किसी अन्य फ़ाइल में वर्ग ए के विस्तार को लिखने से fileprivateसदस्यों के उपयोग की अनुमति नहीं होगी )
विंस

1
यह गलत लगता है। आपको महत्वपूर्ण बिंदु याद आ रहा है। आपको उन वर्गों के बीच अंतर करना होगा जो एक ही मॉड्यूल के अंदर हैं और जो अलग-अलग मॉड्यूल में हैं। यदि वे अलग-अलग मॉड्यूल में हैं, तो publicआपको विरासत में प्राप्त करने की अनुमति नहीं देगा, इसलिए तीसरी छवि गलत है। इसके अलावा, आप हमेशा किसी भी वर्ग के लिए एक्सटेंशन डाल सकते हैं यदि आप इसे देख सकते हैं। एक्सटेंशन पर दृश्यता की व्याख्या करना बहुत अच्छा विचार नहीं है।
सुल्तान

वास्तव में, मुझे अपने डायग्राम के कामों का उल्लेख केवल उसी मॉड्यूल पर करना चाहिए, इसलिए 3 डी इमेज मैं केवल यह चाहता हूं कि उपयोगकर्ता जल्दी से फाइलपाइयर को समझे केवल उसी फाइल पर काम करता है।
स्टीफन चेन

6

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

    class ViewController: UIViewController {
        @IBOutlet var tableView: UITableView!
        //This is not used outside of class Viewcontroller
        private var titleText = "Demo"
        //This gets used in the extension
        fileprivate var list = [String]()
        override func viewDidLoad() {
            navigationItem.title = titleText
        }
    }

    extension ViewController: UITableViewDataSource {
        func numberOfSections(in tableView: UITableView) -> Int {
            return list.count
        }
    }

6

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

फ़ाइल निजी
फ़ाइल-निजी पहुँच अपने स्वयं के परिभाषित स्रोत फ़ाइल के लिए एक इकाई के उपयोग को प्रतिबंधित करती है। कार्यक्षमता के एक विशिष्ट टुकड़े के कार्यान्वयन विवरण को छिपाने के लिए फ़ाइल-निजी पहुंच का उपयोग करें जब उन विवरणों को एक संपूर्ण फ़ाइल के भीतर उपयोग किया जाता है।
सिंटेक्स: fileprivate <var type> <variable name>
उदाहरण: fileprivate class SomeFilePrivateClass {}


निजी
निजी पहुंच एक इकाई के उपयोग को संलग्न घोषणा में और उस घोषणा के एक्सटेंशन तक सीमित कर देती है जो उसी फ़ाइल में हैं । कार्यक्षमता के एक विशिष्ट टुकड़े के कार्यान्वयन विवरण को छिपाने के लिए निजी पहुंच का उपयोग करें जब उन विवरणों को केवल एक घोषणा के भीतर उपयोग किया जाता है।
सिंटेक्स: private <var type> <variable name>
उदाहरण: private class SomePrivateClass {}


यहां सभी एक्सेस स्तरों के बारे में अधिक विवरण दिया गया है: स्विफ्ट - एक्सेस स्तर

इस चित्र को देखें:
फ़ाइल: ViewController.swift
यहां एक्सटेंशन और व्यू कंट्रोलर दोनों एक ही फाइल में हैं, इसलिए निजी चर testPrivateAccessLevelविस्तार में सुलभ है

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


फ़ाइल: TestFile.swift
यहां एक्सटेंशन और व्यू कंट्रोलर दोनों अलग-अलग फाइलों में हैं, इसलिए निजी चर testPrivateAccessLevelएक्सटेंशन में पहुंच योग्य नहीं है।

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

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


यहाँ क्लास ViewController2एक उपवर्ग है ViewControllerऔर दोनों एक ही फाइल में हैं। यहाँ निजी चर testPrivateAccessLevelउपवर्ग में सुलभ नहीं है, लेकिन उपवर्ग में फ़ाइलपाइप सुलभ है।

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


5

हालाँकि @ MartinR's और @ StephenChen का जवाब एकदम सही है, स्विफ्ट 4 में चीजें थोड़ी बदल जाती हैं।

निजी को अब उस वर्ग के लिए निजी माना जाता है जिसमें उसे घोषित किया जाता है और उसके एक्सटेंशन को भी।

फ़ाइलप्रीयर को निजी माना जाता है, उस फाइल में वह वर्ग होता है जिसमें चर को परिभाषित किया जाता है, यह विस्तार होता है, या उसी फ़ाइल में परिभाषित कोई अन्य वर्ग।


5

स्विफ्ट 5 के लिए अपडेट किया गया

निजी बनाम फ़ाइलपार्टी

बेहतर स्पष्टता के लिए प्लेग्राउंड में कोड स्निपेट पेस्ट करें

class Sum1 {
    let a: Int!
    let b: Int!
    private var result: Int?
    fileprivate var resultt: Int?

    init(a : Int, b: Int) {
        self.a = a
        self.b = b
    }

    func sum(){
        result = a + b
        print(result as! Int)
    }
}

let aObj = Sum1.init(a: 10, b: 20)
aObj.sum()
aObj.resultt //File Private Accessible as inside same swift file
aObj.result //Private varaible will not be accessible outside its definition except extensions

extension Sum1{

    func testing() {

        // Both private and fileprivate accessible in extensions
        print(result)
        print(resultt)
    }
}

//If SUM2 class is created in same file as Sum1 ---
class Sum2{

    func test(){

        let aSum1 = Sum1.init(a: 2, b: 2)
        // Only file private accessible
        aSum1.resultt

    }
}

नोट : स्विफ्ट फ़ाइल के बाहर दोनों निजी और फ़ाइलपाइप सुलभ नहीं हैं।


4

फ़ाइलपेयर - एक्सेस कंट्रोलर स्तर फ़ाइल के भीतर है।

केस 1 : यदि हम एक ही क्लास फाइल के साथ एक्सटेंशन बनाते हैं और उसके एक्सटेंशन में फाइलपायरिटी फंक्शन या फाइलपेयर प्रॉपर्टी को एक्सेस करने की कोशिश करते हैं - एक्सेस की अनुमति
केस 2 : अगर हम नई फाइल में क्लास का एक्सटेंशन बनाते हैं - और अब फाइलपाइप फंक्शन या फाइलपेयर को एक्सेस करने की कोशिश करें संपत्ति - पहुंच की अनुमति नहीं है

निजी - अभिगम नियंत्रण स्तर शाब्दिक दायरे में है

स्थिति 1 : यदि संपत्ति या कार्य को कक्षा में निजी घोषित किया जाता है - तो गुंजाइश डिफ़ॉल्ट रूप से कक्षा में है। केस 2 : यदि फ़ंक्शन बॉडी में निजी इंस्टेंस घोषित किया जाता है - तो फंक्शन का दायरा फंक्शन बॉडी तक सीमित रहता है।


3

निम्नलिखित उदाहरण में, भाषा द्वारा संशोधित privateऔर fileprivateपहचाने जाने वाले व्यवहार का निर्माण होता है:

fileprivate func fact(_ n: Int) -> Int {
    if (n == 0) {
        return 1
    } else {
        return n * fact(n - 1)
    }
}

private func gauss(_ n: Int) -> Int {
    if (n == 0) {
        return 0
    } else {
        return n + gauss(n - 1)
    }
}

print(fact(0))
print(fact(5))
print(fact(3))

print(gauss(10))
print(gauss(9))

यह अंतर्ज्ञान के अनुसार है, मुझे लगता है। लेकिन, क्या इसका कोई अपवाद है?

संवेदनापूर्ण संबंध।


3

यह स्विफ्ट 4 के लिए स्पष्टीकरण है। स्विफ्ट 3 के लिए, अंतर निजी है। स्विफ्ट 3 प्राइवेट को इसके विस्तार से नहीं देखा जा सकता है, केवल क्लास ए ही एक्सेस कर सकता है।

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


1
class Privacy {

    fileprivate(set) var pu:Int {
        get {
            return self.pr
        }
        set {
            self.pr = newValue
        }
    }
    private var pr:Int = 0
    fileprivate var fp:Int = 0


    func ex() {
        print("\(self.pu) == \(self.pr) and not \(self.fp)")
    }
}


extension Privacy {

    func ex2() {
        self.pu = 5
        self.ex()
    }

}

मुझे यह पसंद है क्योंकि यह ivars के लिए सुपर सरल है।

फ़ाइलपाइप को निजी (और इसके विपरीत) में बदलने का प्रयास करें और देखें कि संकलन पर क्या होता है ...

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