类 | 结构体 | 枚举 |
---|---|---|
构造器 | ✔ | 原始值类型的枚举, |
析构器 | ✗ | ✗ |
属性 | ✔ | 可以定义计算属性 |
属性观察器 | ✔ | ✗ |
方法 | ✔ | ✔ |
下标脚本 | ✔ | ✔ |
继承 | ✗ | ✗ |
类型转换 | ✗ | ✗ |
扩展 | ✔ | ✔ |
协议 | ✔ | ✔ |
访问控制 | ✔ | ✔ |
构造器
只有当所有存储属性的初始值被确定后,对象的内存才会被完全初始化。
class MyClass {
var property1: Double
var property2: String
var property3: Int = 0
var property4: Int?
let property5 = 0
/**
如果没有给 所有未赋初值的存储属性 定义构造器,
那么像 property1、property2,编译器都会提示让你给这些属性赋初值。
所以要么给它们赋初值、要么给它们定义对应的构造器。
*/
init(property1: Double, property2: String) {
self.property1 = property1
self.property2 = property2
}
}
可变方法
在枚举、结构体的方法中,包括扩展、协议,如果直接修改 self 或其属性的值,编译器会报错:Cannot assign to property: ‘self’ is immutable,可以使用 mutating 修饰该方法。
enum Direction {
case Left
case Right
mutating func next() {
switch self {
case .Left:
self = .Right
case .Right:
self = .Left
}
}
}
struct MyStruct {
var property: String = ""
mutating func test() {
property = ""
}
}
extension Int {
mutating func square() { // 平方
self = self * self
}
}
var a = 10
a.square()
print(a) // 100
类型嵌套
Swift 中的类、结构体和枚举可以进行嵌套。优点是支持访问它外部的成员(包括方法、属性和其他嵌套类型),嵌套可以有多个层次。
class Employee {
var name = ""
var no = 0
var job = ""
var day = WeekDays.Friday
var dept = Department()
struct Department {
var no = 10
var name = "Sales"
}
enum WeekDays{
case Monday,Tuesday,Wednesday,Thursday,Friday
struct Day {
static var message = "Today is ..."
}
}
}
let employee = Employee()
print(employee.day)
print(employee.dept.name)
print(Employee.WeekDays.Day.message)
协议
Swift 为协议提供默认的方法实现
protocol MyProtocol {
var property: String { get }
func method()
}
extension MyProtocol {
// 协议默认的方法实现
func method() {
// self 指遵循该协议,所生成的实例
print("[Default Implement]: \(self) \(self.property)")
}
}
class MyClass: MyProtocol {
var property: String = "my-property"
}
let clz = MyClass()
clz.method() // [Default Implement]: swift_demo.MyClass my-property
print(type(of: MyClass.self)) // MyClass.Type
print(type(of: clz.self)) // MyClass
选择结构体还是类
在比较类和结构体之间的区别之前,先了解两个概念,引用类型和值类型:
引用类型
引用类型在被赋予到一个变量、常量或者被传递到一个函数时,其值不会被拷贝。因此,引用的是已存在的实例本身而不是其拷贝
值类型
它们的实例,以及实例中所包含的任何值类型属性,在代码中传递的时候都会被复制,也就是值拷贝
类和结构体的本质区别:
• 类是引用类型,实例是通过引用传递
• 结构体是值类型,实例是通过值传递
考虑在一个或多个条件适用的情况下创建一个结构体:
- 结构体的主要目的是封装一些相对简单的数据值。
- 当合理的分配或传递该结构的实例时,封装的值将被复制,而不是被引用。
- 结构中存储的任何属性都是值类型,它也可以被复制,而不是被引用。
- 结构体不需要从另一个现有类型继承属性或行为。
优秀的结构体例子包括:
几何形状的大小,可能是封装了宽度属性和高度属性,两者都是 Double 类型。
在 Swift 中,许多基本的数据类型,如字符串、数组和字典都是作为结构体实现的。这意味着当将字符串、数组和字典等数据分配给新的常量或变量时,或者当它们被传递给函数或方法时,就会复制这些数据。
这种行为与 Foundation 库不同:NSString、NSArray 和 NSDictionary 都是作为类实现的,而不是结构。Foundation 中的字符串、数组和字典总是被分配和传递,作为对现有实例的引用,而不是作为副本。
备注:[选择结构体还是类]