2014-09-28 3 views
31

Это было сделано на детской площадке, просто для упрощения.Частный var доступен извне класса

class MyPrivateVar 
{ 
    private var priv: String? 
} 

var myInstance = MyPrivateVar() 

myInstance.priv = "Something" 

Предупреждение о компиляторе. Фактически auto-complete показывает priv без проблем. Я понимаю, что за пределами {} класса я не должен видеть ничего личного, func или var.

Я что-то упустил?

+2

добавления тегов swift2 «globalPrivate», так как это уже не верно swift3 –

ответ

37

Модификаторы доступа в Swift реализованы иначе, чем другие языки. Есть три уровня:

private: доступны только в пределах что конкретный файл

internal: доступен только внутри модуля (проект)

public: доступный из любой

Если не указано иное, все, что вы пишете, - internal по умолчанию.

Swift blog had a post about access control, когда функции были введены в бета-версии 4 и Apple's documentation has a chapter.

+5

"_Привый доступ ограничивает использование объекта в собственном определяющем исходном файле. Используйте частный доступ, чтобы скрыть детали реализации определенной части функциональности. «Я предполагаю, что когда они говорят« файл », они на самом деле это означают. Не слишком важно иметь ограниченную область« private », а не собственный класс , но к физическому файлу, в котором он находится. Я предполагаю, что классы в одном файле не являются просто удобными, он имеет функциональное значение. Может быть, имеет какое-то отношение к «закрытым» заголовкам, которые не копируются снаружи. – bauerMusic

+4

Сообщение в блоге, связанное с ответом в некоторые из их причин для этой нестандартной системы, и у них есть [другая публикация о том, почему они не включали «защищенные»] (https://developer.apple.com/swift/blog/?id=11), которые более подробно. –

+4

В Swift 3 это изменится, поэтому 'private' ограничивает объявление текущей областью, а' fileprivate' (новый модификатор доступа) будет делать то, что 'private' делал перед Swift 3. [This article] (https://swifting.io/blog/2016/08/17/22-swift-3-access-control-beta-6/?u tm_campaign = Этот% 2BWeek% 2Bin% 2BSwift & utm_medium = web & utm_source = This_Week_in_Swift_100) имеет хорошее резюме модификаторов доступа в Swift 3. – keithbhunter

7

Примечание: этот ответ для Swift 2


Свифт языка программирования состояний:

Swift обеспечивает три уровня доступа для объектов в рамках кода. Эти уровни доступа относятся к исходному файлу, в котором определен объект , а также относительно модуля, к которому принадлежит исходный файл .

Если вы не прошли тест private уровня доступа с помощью Swift, это поможет вам шаг за шагом.

1/Создать новый проект Xcode.

2/Создать файл, MyPrivateVar.swift, и добавьте в него следующий код:

class MyPrivateVar { 

    private var priv: String? = nil 

} 

3/Создать второй файл, MySecondClass.скор, и добавьте в него следующий код:

class MySecondClass { 

    init() { 
     var myPrivateVar = MyPrivateVar() 
     myPrivateVar.priv = "some string" 
    } 

} 

Xcode будет немедленно дать вам Swift сообщение об ошибке компилятора:

«MyPrivateVar» не имеет элемент с именем «собств»

4/Теперь удалите два предыдущих файла из вашего проекта и создайте один файл TwoClassesInAFile.swift со следующим кодом:

class MyPrivateVar { 

    private var priv : String? = nil 

} 

class MySecondClass { 

    init() { 
     var myPrivateVar = MyPrivateVar() 
     myPrivateVar.priv = "some string" 
    } 

} 

На этот раз, вы не получите сообщение об ошибке Swift компилятора, и вы будете иметь возможность получить доступ к MyPrivateVar «S priv частной собственности от MySecondClass потому что priv и MySecondClass находятся в одном файле (ваш TwoClassesInAFile.swift файла) ,

Кроме того, уровни доступа также работают для глобальных переменных. Например, Xcode не будет давать какие-либо ошибки компилятора, если следующий код является частью того же ViewController.swift файла:

import UIKit 

private var globalPrivate : String? = nil 

class ViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     globalPrivate = "some string" 
     println(globalPrivate) 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 

} 

Однако, если определить globalPrivate вне ViewController.swift, Xcode будет сообщение об ошибке:

использование неразрешенного идентификатора

+0

Использул Playground просто для двойной проверки. Исходная проблема произошла в файле контроллера вида в проекте. Я отметил, что я использовал Playground для упрощения проблемы. – bauerMusic

+0

** Точка № 4 неверна в swift 3 и xcode 8. ** класс AccessModifiersClass { приватный var privV: String? внутренний var inteV: String? public var publV: String? var defV: String? } класс CheckPoint { Init() { globalPrivate = "некоторая строка" пусть lVar = AccessModifiersClass() lVar.priv = "Public" lVar.inteV = "Внутренний" lVar.publV = «Публичный» lVar.defV = «по умолчанию» } – Abhishek

Смежные вопросы