1 常量
swift中,可以使用关键字let来声明常量。我们通过以下几个关键点来认识常量。
1.1 只能赋值一次
常量只能被赋值一次,如果重复赋值,会报错。以下图为例:
1.2 常量在初始化之前,不能使用
如下面的示例,对常量a进行了声明,并且是Int型,但是没有初始化,直接使用则会报错。同样,变量age也没有初始化,直接使用也会报错。
声明即赋值,或者先声明使用前再赋值。如下面的两个示例:
// 声明即赋值
let age = 28
print(age)
// 先声明,使用前赋值
let height : Int
height = 175
print(height)
1.3 不要求在编译时期确定,但使用之前必须赋值一次
示例中age3是一个常量,并通过一个函数赋值,所以在编译期间并没有确定值,而是在执行期间确定。
1.4 常量需要确定数据类型
常量在声明后,如果没有确定数据类型,也没有赋值,会报错。
2 标识符
-
比如常量、变量、函数,几乎可以使用任何字符
下面的示例中,使用一些特殊的图案,来对常量、变量、函数进行命名:
-
标识符不能以数字开头,不能包含制表符、空白字符、箭头等特殊字符
标识符依然会有一些限制要求,比如不能以数字开头,不能使用制表符、空格等特殊字符。同时,在编码过程中,为了更加
易于理解、扩展和维护,我们还是要遵循一些编码规范:- 清晰性:命名清晰,功能清晰
- 可读性:便于快速理解方法作用
- 可维护性:减少因命名歧义引发的
Bug,后期代码微调简单 - 一致性:团队协作风格统一
3 常见数据类型
3.1 Objective-C数据类型
首先回顾一下Objective-C的数据类型。
- 基本数据类型
Objective-C的基本数据类型与C语言类似,主要包括:- 整型 如
int(通常占用4字节,表示范围为-2,147,483,648至2,147,483,647)、short(通常占用2字节,表示范围为-32,768至32,767)、long(通常占用4或8字节,取决于平台)、long long(至少占用8字节,表示范围更大)。 - 浮点型 如
float(单精度浮点数,通常占用4字节)、double(双精度浮点数,通常占用8字节)、long double(高精度浮点数,具体大小依赖于编译器实现)。 - 字符型 如
char(通常占用1字节,用于存储单个字符)。 - 布尔型 如
BOOL(用于表示真假值,通常占用1字节)。
- 整型 如
- 对象数据类型
Objective-C的核心特性之一是面向对象的数据类型,比如Foundation框架中提供的一些复合型对象:- 字符串:如
NSString(不可变字符串)和NSMutableString(可变字符串)。 - 数组:如
NSArray(不可变数组)和NSMutableArray(可变数组)。 - 字典:如
NSDictionary(不可变字典)和NSMutableDictionary(可变字典)。 - 数字:如
NSNumber。 - 数据:如
NSData。
- 字符串:如
- 扩展数据类型
Objective-C还支持一些扩展的数据类型,包括:- 指针类型:如
int*,float*,NSObject*等。 - 结构体类型:如
CGRect,CGSize,CGPoint等。 - 枚举类型:如
NSComparisonResult,UITableViewStyle等。 - 类型定义:通过
typedef关键字定义自定义数据类型,如typedef enum,typedef struct等。 - 其他类型:如
NSUInteger,NSInteger,SEL等。
- 指针类型:如
3.2 Swift数据类型
Swift 数据类型主要包括基本数据类型(如整数、浮点数、布尔值、字符和字符串)和复合数据类型(如数组、元组、可选类型等)。
-
基本数据类型 如整数、浮点数、布尔值、字符和字符串:
- 整数类型:
Int:平台相关长度(32位系统为32位,64位系统为64位),建议默认使用以提高代码一致性。变体:Int8 Int16 Int32 Int64(有符号)和UInt8 UInt16等(无符号),需显式指定。 - 浮点数类型
Float:32位单精度浮点数(约6位小数精度)。Double:64位双精度浮点数(约15位小数精度,推荐默认使用)。 - 布尔类型
Bool:仅包含true和false,用于逻辑判断。 - 字符与字符串
Character:单个Unicode字符(如"A")。String:文本数据,支持插值和多行语法(如"Hello")。
- 整数类型:
-
复合数据类型 数组、元组、可选类型等:
- 数组与字典
Array:有序同类型集合。Dictionary:键值对集合(如["key": "value"])。 - 元组与可选类型
Tuple:异构值组合(如(1, "error"))。Optional:表示值可能存在为nil(如Int?)。
- 数组与字典
-
引用类型 类(
class)
3.3 Swift数据类型的底层实现
我们知道Objective-C对象数据类型class类底层实现是结构体,这个结构体的定义在runtime源码中。比如Foundation库中提供的类型,如NSString、NSArray等,以及我们自定义的继承自NSObject的类,这些底层都是结构体。在iOS底层学习——OC对象的本质与isa中也有过探索。
在Swift中,引用类型类(class)底层并不是结构体来实现的,但是一些基本数据类型如Int、Float、Double、Character、String以及Array、Dictionary却是定义为结构体。主要是因为它们作为值类型在性能和内存管理上具有优势。
下图对swift数据类型进行了归类:
我们在开发工具上,也能够看到,Int是一个结构体:
快速跳转到定义(Jump to Definition),Command + 点击鼠标左键快捷键,也能看到,源码中Int被定义成为一个public型的结构体。
我们知道结构体占用的内存空间,取决于结构体内部所有变量占用空间之和,这里提出一个疑问:将这些基本数据类型定义成结构体,难道不会增加复杂度,增加内存使用吗?其实swift内部做了优化,后面我们再深入探索。
4 部分数据类型的使用
4.1 整型类型
Swift提供了多种整型类型,如Int8、Int16、Int32、Int64、UInt8、UInt16、UInt32、UInt64。Int8表示占8位,1个字节;UInt8中U表示无符号。- 在
32bit平台,Int等价于Int32;64bit平台,Int等价于Int64。 - 一般情况下,我们使用
Int即可,除非对内存占用空间有强制性要求。
可以通过max、min属性,了解数据类型对应的最大值和最小值。(注意这里的max、min是属性,不是函数方法)
4.2 浮点型
Float32位,精度只有6位Double64位,精度至少15位- 初始化一个浮点型时,如果没有声明类型,默认是
Double型
4.3 不同进制表示方式
let intDecimal = 17// 十进制let intBinary = 0b10001// 二进制let intOctal = 0o21// 八进制let intHexadecimal = 0x11// 十六进制
4.4 字符型
- 字符型和字符串一样,使用双引号
“” - 初始化一个字符型时,如果没有声明类型,默认是
String型 - 字符可以存储
ASCII字符、Unicode字符
4.5 数组、字典
let array = ["a", "b", "c"]let dic = ["a" : 12, "b" : 13, "c" : 21]- 字典类型也是使用
[]
在原生的容器类型中,他们都是泛型的,也就是我们在一个集合中,只能放同一种类型的元素。
如果我们要把不相关的类型,放到同一个容器类型中的话,比较容易想到的是使用 Any和AnyObject,如下面的示例,再或者使用NSArray、NSDictionary。
let array : [Any] = ["a", "b", "c", 1]let dic : [String : Any] = ["a" : 12, "b" : "13"]
4.6 类型转换
-
整数转换
如下图的示例中,
age1和age2虽然都是整型,但是其占用的存储空间是不同的,所以是不能直接相加的。因为
Int8占用8位一个字节,而Int16占用两个字节,所以可以将age1转换为Int6,再相加,而age3也自动变成Int16型。 -
整数、浮点数转换
如下图所示,整型和浮点型类型不批配,是不可以直接相加的:
可以将
Int型转为浮点型,此时intp也为Double型:但是下面这种方式是可以的,字面量可以直接相加,因为数字字面量本身没有明确的类型:
4.7 元祖tuple
将多个不同数据类型组合赋予一个变量,可以通过序号来访问对应位置上的值:
可以将定义的元祖赋予一个元祖,对应位置上元素会自动赋值:
如果元素不需要赋值,可以直接用_来代替:
在定义元祖时,还可以给每个元素设置一个key: