Учебники

Swift — Контроль доступа

Для ограничения доступа к блокам кода, модулям и абстракциям осуществляется контроль доступа. Классы, структуры и перечисления могут быть доступны в соответствии с их свойствами, методами, инициализаторами и индексами с помощью механизмов контроля доступа. Константы, переменные и функции в протоколе ограничены и имеют доступ как глобальный, так и локальный через контроль доступа. Контроль доступа, применяемый к свойствам, типам и функциям, может называться «сущностями».

Модель контроля доступа основана на модулях и исходных файлах.

Модуль определяется как единая единица распределения кода и может быть импортирован с использованием ключевого слова «импорт». Исходный файл определяется как один файл исходного кода с модулем для доступа к нескольким типам и функциям.

Язык Swift 4 предоставляет три различных уровня доступа. Это публичный, внутренний и частный доступ.

S.No Уровни доступа и определение
1

общественного

Позволяет обрабатывать объекты в любом исходном файле из их определяющего модуля, исходный файл из другого модуля, который импортирует определяющий модуль.

2

внутренний

Позволяет использовать сущности в любом исходном файле из их определяющего модуля, но не в любом исходном файле за пределами этого модуля.

3

Частный

Ограничивает использование объекта собственным определяющим исходным файлом. Частный доступ играет роль, чтобы скрыть детали реализации определенной функциональности кода.

общественного

Позволяет обрабатывать объекты в любом исходном файле из их определяющего модуля, исходный файл из другого модуля, который импортирует определяющий модуль.

внутренний

Позволяет использовать сущности в любом исходном файле из их определяющего модуля, но не в любом исходном файле за пределами этого модуля.

Частный

Ограничивает использование объекта собственным определяющим исходным файлом. Частный доступ играет роль, чтобы скрыть детали реализации определенной функциональности кода.

Синтаксис

public class SomePublicClass {}
internal class SomeInternalClass {}
private class SomePrivateClass {}

public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}

Контроль доступа для типов функций

Некоторые функции могут иметь аргументы, объявленные внутри функции без каких-либо возвращаемых значений. Следующая программа объявляет a и b в качестве аргументов функции sum (). Внутри самой функции значения аргументов a и b передаются путем вызова вызова функции sum (), и ее значения печатаются, тем самым исключая возвращаемые значения. Чтобы сделать возвращаемый тип функции закрытым, объявите общий уровень доступа функции с модификатором private.

Live Demo

private func sum(a: Int, b: Int) {
   let a = a + b
   let b = a - b
   print(a, b)
}

sum(a: 20, b: 10)
sum(a: 40, b: 10)
sum(a: 24, b: 6)

Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —

30 20
50 40
30 24

Контроль доступа для типов перечисления

Live Demo

public enum Student {
   case Name(String)
   case Mark(Int,Int,Int)
}
var studDetails = Student.Name("Swift 4")
var studMarks = Student.Mark(98,97,95)

switch studMarks {
   case .Name(let studName):
      print("Student name is: \(studName).")
   case .Mark(let Mark1, let Mark2, let Mark3):
      print("Student Marks are: \(Mark1),\(Mark2),\(Mark3).")
   
}

Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —

Student Marks are: 98,97,95

Перечисление на языке Swift 4 автоматически получает один и тот же уровень доступа для отдельных случаев перечисления. Рассмотрим, например, для доступа к имени ученика и отметкам, закрепленным в трех предметах. Имя перечисления объявляется как ученик, и члены, присутствующие в классе перечисления, являются именами, принадлежащими строковому типу данных, метки представляются как mark1, mark2 и mark3 типа данных Integer. Чтобы получить доступ либо к имени студента, либо к оценкам, которые он набрал. Теперь регистр коммутатора будет печатать имя студента, если этот блок регистра будет выполнен, иначе он будет печатать метки, закрепленные за студентом. Если оба условия не выполняются, будет выполнен блок по умолчанию.

Контроль доступа для подклассов

Swift 4 позволяет пользователю создавать подклассы для любого класса, к которому можно получить доступ в текущем контексте доступа. Подкласс не может иметь более высокий уровень доступа, чем его суперкласс. Пользователю запрещено писать открытый подкласс внутреннего суперкласса.

public class cricket {
   internal func printIt() {
      print("Welcome to Swift 4 Super Class")
   }
}

internal class tennis: cricket {
   override internal func printIt() {
      print("Welcome to Swift 4 Sub Class")
   }
}

let cricinstance = cricket()
cricinstance.printIt()

let tennisinstance = tennis()
tennisinstance.printIt()

Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —

Welcome to Swift Super Class
Welcome to Swift Sub Class

Контроль доступа для констант, переменных, свойств и подписок

Константа, переменная или свойство Swift 4 не могут быть определены как общедоступные, чем их тип. Недопустимо писать публичное свойство с закрытым типом. Аналогично, индекс не может быть более открытым, чем его индекс или тип возвращаемого значения.

Когда константа, переменная, свойство или индекс используют частный тип, константа, переменная, свойство или индекс также должны быть помечены как закрытые —

private var privateInstance = SomePrivateClass()

Добытчики и сеттеры

Методы получения и установки констант, переменных, свойств и индексов автоматически получают тот же уровень доступа, что и константа, переменная, свойство или индекс, к которому они принадлежат.

Live Demo

class Samplepgm {
   var counter: Int = 0{
      willSet(newTotal) {
         print("Total Counter is: \(newTotal)")
      }
      didSet {
         if counter > oldValue {
            print("Newly Added Counter \(counter - oldValue)")
         }
      }
   }
}

let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800

Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —

Total Counter is: 100
Newly Added Counter 100
Total Counter is: 800
Newly Added Counter 700

Контроль доступа для инициализаторов и инициализаторов по умолчанию

Пользовательским инициализаторам может быть назначен уровень доступа, меньший или равный типу, который они инициализируют. Требуемый инициализатор должен иметь тот же уровень доступа, что и класс, к которому он принадлежит. Типы параметров инициализатора не могут быть более закрытыми, чем собственный уровень доступа инициализатора.

Чтобы объявить каждый подкласс инициализируемого ключевого слова ‘required’, необходимо определить его перед функцией init ().

Live Demo

class classA {
   required init() {
      let a = 10
      print(a)
   }
}
class classB: classA {
   required init() {
      let b = 30
      print(b)
   }
}
let res = classA()
let print = classB()

Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —

10
30
10

Инициализатор по умолчанию имеет тот же уровень доступа, что и инициализируемый им тип, если только этот тип не определен как открытый. Если инициализация по умолчанию определена как общедоступная, она считается внутренней. Когда пользователю требуется, чтобы открытый тип был инициализируемым с инициализатором без аргументов в другом модуле, явным образом предоставьте открытый инициализатор без аргументов как часть определения типа.

Контроль доступа к протоколам

Когда мы определяем новый протокол для наследования функциональных возможностей от существующего протокола, оба должны быть объявлены одинаковыми уровнями доступа для наследования свойств друг друга. Управление доступом Swift 4 не позволит пользователям определять «открытый» протокол, который наследуется от «внутреннего» протокола.

public protocol tcpprotocol {
   init(no1: Int)
}
public class mainClass {
   var no1: Int      // local storage
   init(no1: Int) {
      self.no1 = no1 // initialization
   }
}
class subClass: mainClass, tcpprotocol {
   var no2: Int
   init(no1: Int, no2 : Int) {
      self.no2 = no2
      super.init(no1:no1)
   }
   
   // Requires only one parameter for convenient method
   required override convenience init(no1: Int) {
      self.init(no1:no1, no2:0)
   }
}

let res = mainClass(no1: 20)
let print = subClass(no1: 30, no2: 50)

print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")

Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —

res is: 20
res is: 30
res is: 50

Контроль доступа для расширений

Swift 4 не позволяет пользователям предоставлять явный модификатор уровня доступа для расширения, когда пользователь использует это расширение для добавления соответствия протокола. Уровень доступа по умолчанию для каждой реализации требования протокола в расширении обеспечивается собственным уровнем доступа к протоколу.

Контроль доступа для дженериков

Обобщения позволяют пользователю указывать минимальные уровни доступа для доступа к ограничениям типа для его параметров типа.

Live Demo

public struct TOS<T> {
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }
}

var tos = TOS<String>()
tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Type Parameters")
print(tos.items)

tos.push(item: "Naming Type Parameters")
print(tos.items)
let deletetos = tos.pop()

Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —

[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Type Parameters]
[Swift 4, Generics, Type Parameters, Naming Type Parameters]

Контроль доступа для псевдонимов типа

Пользователь может определить псевдонимы типов для обработки различных типов контроля доступа. Один и тот же уровень доступа или разные уровни доступа могут быть определены пользователем. Когда псевдоним типа ‘private’, его связанные члены могут быть объявлены как ‘private, internal of public type’. Когда псевдоним типа является общедоступным, члены не могут быть псевдонимами в качестве «внутреннего» или «частного» имени.

Все псевдонимы типов, которые вы определяете, рассматриваются как отдельные типы для целей контроля доступа. Псевдоним типа может иметь уровень доступа меньше или равный уровню доступа типа псевдонима. Например, псевдоним частного типа может иметь псевдоним частного, внутреннего или открытого типа, но псевдоним открытого типа не может иметь псевдоним внутреннего или частного типа.

public protocol Container {
   associatedtype ItemType
   mutating func append(item: ItemType)
   var count: Int { get }
   subscript(i: Int) -> ItemType { get }
}
struct Stack<T>: Container {
   // original Stack<T> implementation
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }
   
   // conformance to the Container protocol
   mutating func append(item: T) {
      self.push(item: item)
   }
   var count: Int {
      return items.count
   }
   subscript(i: Int) -> T {
      return items[i]
   }
}
func allItemsMatch<
   C1: Container, C2: Container
   where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
   (someContainer: C1, anotherContainer: C2) -> Bool {
   
   // check that both containers contain the same number of items
   if someContainer.count != anotherContainer.count {
      return false
   }
   
   // check each pair of items to see if they are equivalent
   for i in 0..<someContainer.count {
      if someContainer[i] != anotherContainer[i] {
         return false
      }
   }
   // all items match, so return true
   return true
}
var tos = Stack<String>()
tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Where Clause")
print(tos.items)

var eos = ["Swift 4", "Generics", "Where Clause"]
print(eos)

Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —

[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Where Clause]
[Swift 4, Generics, Where Clause]

Быстрое кодирование и декодирование

Swift 4 представляет новый Codable Protocol, который позволяет вам сериализовывать и десериализовывать пользовательские типы данных без написания какого-либо специального кода и без необходимости беспокоиться о потере типов значений.

struct Language: Codable {
   var name: String
   var version: Int
}
let swift = Language(name: "Swift", version: 4)
let java = Language(name: "java", version: 8)
let R = Language(name: "R", version: 3

Обратите внимание, что Langauage соответствует Codable Protocol. Теперь мы преобразуем его в представление данных Json, используя одну простую строку.

let encoder = JSONEncoder()
if let encoded = try? encoder.encode(java) {
   //Perform some operations on this value.
}

Swift автоматически закодирует все значения внутри вашего типа данных.

Вы можете декодировать данные, используя функцию декодера, как

let decoder = JSONDecoder()
if let decoded = try? decoder.decode(Language.self, from: encoded) {
   //Perform some operations on this value.
}

И JSONEncoder, и его аналог PropertyListEncoder со списком свойств имеют множество опций для настройки их работы.