无涯教程-Swift - 修饰符

73 阅读7分钟

协议中的常量,变量和函数受到限制,并允许通过访问控制以全局和局部方式进行访问。

Swift 4语言提供了三种不同的访问级别。它们是公共,内部和私有访问权限。

S.No Access Levels & Definition
1

Public

使实体可以在其定义模块的任何源文件中进行处理,而在导入定义模块的另一个模块的源文件中进行处理。

2

Internal

使实体可以在其定义模块的任何源文件中使用,但不能在该模块外部的任何源文件中使用。

3

Private

将实体的使用限制为自己定义的源文件。私有访问扮演着隐藏特定代码函数的实现细节的角色。

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

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

类型修饰符

某些函数可能在函数内部声明了参数而没有任何返回值,下面的程序将a和b声明为sum()函数的参数。在函数本身内部,通过调用函数调用sum()传递参数a和b的值,并打印其值,从而消除返回值。要将函数的返回类型设为私有,请使用private修饰符声明函数的总体访问级别。

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

枚举类型控制

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允许用户将可以在当前访问上下文中访问的任何类作为子类,子类不能具有比其父类更高的访问级别,禁止用户编写内部超类的公共子类。

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()

Getters and Setters

常量,变量,属性和下标的获取器和设置器将自动获得与其所属的常量,变量,属性或下标相同的访问级别。

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

默认初始化程序

可以为自定义初始化程序分配一个小于或等于其初始化类型的访问级别,所需的初始化程序必须与其所属的类具有相同的访问级别。

要声明initializerequired关键字的每个子类,都需要在init()函数之前定义。

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

默认初始化程序具有与其初始化类型相同的访问级别,除非该类型定义为public。当默认初始化定义为public时,将其视为内部的。当用户需要使用另一个模块中的无参数初始化器初始化公共类型时,请明确提供公共无参数初始化器作为类型定义的一部分。

协议访问控制

当我们定义新协议以继承现有协议的函数时,必须将两者声明为相同的访问级别,以彼此继承属性。 

public protocol tcpprotocol {
   init(no1: Int)
}
public class mainClass {
   var no1: Int      //本地存储
   init(no1: Int) {
      self.no1=no1 // 初始化
   }
}
class subClass: mainClass, tcpprotocol {
   var no2: Int
   init(no1: Int, no2 : Int) {
      self.no2=no2
      super.init(no1:no1)
   }

//只需要一个参数即可方便的方法 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不允许用户为扩展名提供显式的访问级别修饰符。扩展中每个协议要求实现的默认访问级别都具有其自己的协议访问级别。

泛型的访问控制

泛型允许用户指定最低访问级别,以访问其类型参数上的类型约束。

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,public, internal"。当类型别名为public时,成员不能作为"internal"或"private"名称别名

出于访问控制的目的,您定义的任何类型别名都被视为不同的类型,类型别名的访问级别可以小于或等于其别名的访问级别。例如,私有类型别名可以别名私有,内部或公共类型,但是公共类型别名不能别名内部或私有类型。

public protocol Container {
   associatedtype ItemType
   mutating func append(item: ItemType)
   var count: Int { get }
   subscript(i: Int) -> ItemType { get }
}
struct Stack<T>: Container {
   //原始 Stack<T> 实现
   var items=[T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }

//符合容器协议 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 {

//检查两个容器是否包含相同数量的项目 if someContainer.count != anotherContainer.count { return false }

//检查每对项目,看看它们是否相等 for i in 0..<someContainer.count { if someContainer[i] != anotherContainer[i] { return false } } //所有项目都匹配,所以返回 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]

Encoding and Decoding

Swift 4引入了新的 Codable 协议,使您无需编写任何特殊代码即可序列化和反序列化自定义数据类型,而不必担心丢失值类型。

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

请注意,语言符合可编码协议。现在,我们将使用简单的一行将其转换为Json数据表示形式。

let encoder=JSONEncoder()
if let encoded=try? encoder.encode(java) {
   //对这个值执行一些操作。
}

Swift将自动对数据类型内的所有值进行编码。

您可以使用解码器函数对数据进行解码,例如

let decoder=JSONDecoder()
if let decoded=try? decoder.decode(Language.self, from: encoded) {
   //对这个值执行一些操作。
}

JSONEncoder及其对应的属性列表PropertyListEncoder都有许多用于自定义其工作方式的选项。

参考链接

www.learnfk.com/swift/swift…