引言:结构体和类作为一种通用而又灵活的结构,成为了人们构建代码的基础。你可以使用定义常量、变量和函数的语法,为你的结构体和类定义属性、添加方法。
结构体与类的共同点:
1.都可定义属性且可储存值
2.都可以定义方法用于提供功能
3.都可在初始化方法内对属性进行初始化赋值
4.都可以通过扩展方法来实现自身其他功能
5.都可以遵循某种协议提供特定功能
结构体与类的主要不同点:
1.类可以被继承,结构体不可以
2.可以对类进行多次引用计数
1.定义:
结构体和类有着相似的定义方式。你通过 struct 关键字引入结构体,通过 class 关键字引入类,并将它们的具体定义放在一对大括号中:
struct PersonInfo {
//结构体内容
}
代表创建了一个空的结构体
class ViewModel{
//类内容
}
代表创建了一个空的类
调用:let person = PersonInfo() 或 let person = PersonInfo.init()
let view = ViewModel() 或 let view = ViewModel.init()
2.属性以及赋值、取值
(1)定义属性
结构体:
struct PersonInfo {
var name:String
var age:Int
}
调用:let person = PersonInfo(name: "浩然", age: 3) 或 let person = PersonInfo.init(name: "浩然", age: 3)
**注意:若结构体在创建属性时未声明属性值,则必须在结构体初始化时对属性进行赋值**
类:
class ViewModel{
var width:Double?
var height:Double?
}
注意:结构体在创建属性时可以不必声明属性是否有值,而类在创建属性时必需声明属性是否有值可以后缀"?"或者直接给属性赋默认值
调用:let view = ViewModel.init() 或 let view = ViewModel()
}
(2)赋值:可默认赋值、初始化赋值、直接赋值
结构体:
1.若在创建属性时可默认赋值,如:
struct PersonInfo {
var name = "浩然"
var age = 3
}
代表name的默认值是浩然,age的默认值是3(默认赋值时,系统会自动为该属性匹配类,可不书写类名)
调用:let person = PersonInfo.init() 属性有默认值时,结构体初始化可不必对属性进行赋值
类:
class ViewModel{
var width = 100.00
var height = 200.00
}
代表width的默认值是100.00,height的默认值是200.00
调用:let view = ViewModel()
2.初始化赋值,如:
结构体:
let person = PersonInfo(name: "浩然", age: 3) 代表结构体的属性:"name"赋值"浩然","age"赋值3
类: 类在初始化时除非自定义初始化方法,否则默认没有属性初始化赋值(自身初始化自带的除外),如:
class ViewModel{
var width = 100.00
var height = 200.00
init(one:Double,two:Double) {
self.width = one
self.height = two
}
调用:let view = ViewModel.init(one: 150.00, two: 250.00)
3.直接赋值,在类或结构体初始化后,可直接对其属性进行赋值,如:
结构体:
var person = PersonInfo.init() 注意若想在结构体初始后对其属性赋值,那么在初始化时需要用var对其声明
person.name = "儿子"
person.age = 5
类:
let view = ViewModel()
view.width = 200.00
view.height = 300.00
(3)取值
类和结构体都是通过直接属性访问进行取值,如:
结构体:
let person = PersonInfo.init(name: "儿子", age: 10)
print("名字:\(person.name),年龄:\(person.age)")
输出:名字:儿子,年龄:10
类:
let view = ViewModel.init(one: 200.00, two: 300.00)
输出:宽度:200.0,高度:300.0
3.结构体属于值类型
值类型是这样一种类型,当它被赋值给一个变量、常量或者被传递给一个函数的时候,其值会被拷贝。且两者都是独立的个体,互不干扰,映射
Swift 中所有的基本类型:整数(integer)、浮点数(floating-point number)、布尔值(boolean)、字符串(string)、数组(array)和字典(dictionary),都是值类型,其底层也是使用结构体实现的,这也就表明了结构体只有在用var声明时,才可以修改属性值,如:
let person = PersonInfo.init(name: "儿子", age: 10)
var info = person
info.name = "啾啾"
print("\(info.name),\(person.name)")
输出:啾啾,儿子
可见info与person是两个独立的结构体,互不干扰
与值类型不同,引用类型在被赋予到一个变量、常量或者被传递到一个函数时,其值不会被拷贝。因此,使用的是已存在实例的引用,而不是其拷贝。只有当类初始化时才会在内存里开辟一个新地址,若是直接赋值只是对其引用
let view = ViewModel.init(one: 200.00, two: 300.00)
let info = view
info.width = 300
print("\(info.width),\(view.width)")
输出:300.0,300.0
可见当view赋值给info时,修改info属性值时,会影响到view