常量和变量
使用关键字let
来声明常量
:
只能赋值1次
它的值不要求在编译时期确定,但使用之前必须赋值1次
常量、变量在初始化之前,都不能使用
使用关键字var
来声明变量
:
let count = 10
var n = 10
可以在一行中声明多个变量或常量,用逗号隔开
var x = 0.0, y = 0.0, x=0.0
类型标注
(1)在声明一个变量或常量的时候提供类型标注,来明确变量或常量能够储存值得类型
(2)添加类型标注的方法是在变量或常量的名字后边加一个冒号,再跟一个空格,最后加上要使用的类型名称
(3)可以在一行中定义多个相关的变量为相同的类型,用逗号隔开,只要在最后的变量名字后加上类型标注
var name: String
name = "liven"
变量和常量命名
常量和变量的名字几乎可以使用任何字符,甚至包括Unicode字符
常量和变量的名字不能包括空白字符、数字符合、箭头、保留的(或者无效的)Unicode码位、连线和制表符。也不能以数字开头,尽管数字几乎可以使用在名字其他的任何地方
打印常量和变量
let name = "liven"
print("我的名字:\(name)")
数值类型
Swift 提供了8,16,32,64位编码的有符号和无符号的整数
命名方式:例如8位无符号整数
的类似是UInt8
, 32位有符号整数
的类型是Int32
通过min
和 max
属性来访问每个整数类型的最小值和最大值
整数
Swift 提供了一个额外的整数类型: Int ,它拥有与当前平台的原生字相同的长度
同时Swift也提供UInt类型,来表示平台长度相关的无符号整数
建议在用到整数的地方都是用Int
浮点类型
Double
: 64位浮点数,至少有15位数字的精度
Float
: 32位浮点数,至少有6位数字的精度
在两种类型都可以的情况下,推荐使用Double类型
布尔类型
Bool :true
和 false
Swift 的类型安全机制会阻止你用一个非布尔量的值替换掉Bool
类型别名
类型别名是一个为已存在类型定义的一个可选择的名字
用关键字typealias定义一个类型的别名
当你想通过在一个在上下文中看起来更合适可具有表达式的名字来引用一个已存在的类型时,这时别名就非常有用了
typealias zhengshu = UInt8
let age:zhengshu = 32
Tuple
元组把多个值合并成单一的复合型的值
元组内的值可以是任何类型,而且可以不必是同一个类型
let error = (1,"没有权限")
print(error.0)
print(error.1)
元组中的每一个元素可以指定对应的元素名称
如果没有指定名称的元素也可以使用下标的方式来引用
let error = (errorCode:1,errorMessage:"没有权限")
print(error.errorCode)
print(error.errorMessage)
用var
定义的元组就是可变元组
,let
定义的就是不可变元组
不管是可变还是不可变元组,元组在创建后就不能增加和删除元素
可以对可变元组的元素进行修改,但是不能改变其类型
any
类型可以改为任何类型
var error:(Any,String) = (1,"没有权限")
error.0 = 2
print(error)
error.0 = "abc"
print(error)
Tuple分解
以将一个元组的内容分解成单独的常量或变量
如果只需要使用其中的一部分数据,不需要的数据可以使用下滑线(_)代替
/// 将一个元组的内容分解成单独的常量或变量
let error = (1,"没有权限")
let (errorCode,errorMessage) = error
print(errorCode)
�print(errorMessage)
/// 将不需要的数据,使用下滑线(_)代替
let error = (1,"没有权限")
let (_,errorMessage) = error
print(errorMessage)
Optional
在Swift中只有可选项可以赋值为nil
/// 第一行会报错,第二行是正常的
var str:String = nil
var str:String? = nil
通过在
变量类型后面加 ?
表示:
这里有一个值,它等于x
或者
这里根本没值
可以通过给可选变量赋值一个nil来将之设置为没有值
在Object-C中nil是一个指向不存在对象的指针
在Swift中,nil不是指针,它是值缺失的一种特殊类型
,任何类型的可选项都可以设置成nil而不仅仅是对象类型
可选项是没法直接使用的
需要用! 展开
之后才能使用(意思是我知道这个可选项里边有值,展开吧)
使用!来获取一个不存在的可选值会导致运行错误,在使用!强制展开之前必须确保可选项中包含一个非nil的值
var str: String?
/// 这句会报错,因为str没有一个非nil的值
let cout = str!.count
Optional-绑定
- 可以使用可选项绑定来判断可项是否包含值,如果包含就把值赋给一个临时的常量或变量
- 可先绑定可以与if 和 while 的语句使用来检查可选项内部的值,并赋值给一个变量或常量
- 同一个if语句中包含多个可选项绑定,用逗号分隔即可。如果任一可选绑定结果是nil或者布尔值为false,那么整个if判断会被看做false
/// 定义一个可选项变量 str,类型是String
let str:String? = "abc"
/// (1)判断展开
/// 如果str 不是nil,那么将str的值赋值给变量value
if let value = str {
let count = value.count
print(count)
}
/// (2) 强制展开:不建议使用,
/// 因为可选项的值如果不是”abc“,而是nil那么就会报错
let count = str!.count
///(3)可以先判断可选项不是nil,然后再用强制的方式展开
if str != nil {
let count = str!.count
print(count)
}
/// 等同于这种写法
//let str: Optional<String> = "abc"
//if str != nil {
// let count = str.unsafelyUnwrapped.count
// print(count)
//}
Optional - 隐式展开
有些可选项一旦被设定值之后,就会一直拥有值
,在这种情况下,就可以去掉检查的需求,也不必每次访问的时候都进行展开
通过在声明的类型后边添加一个叹号(String!)而非问号(String?)来书写隐式展开可选项
隐式展开可选项主要被用在Swift类的初始化过程
中
/// 可选项的隐式展开
let str:String! = "abc"
let count = str.count
print(count)
Optional - 可选链
可选项后面加问号
如果可选项不为nil,返回一个可选项结果,否则返回nil
var str:String? = "abc"
/// 这里count 也是可以看做一个可选项
let count = str?.count
if count != nil {
let lastIndex = count! - 1
print(lastIndex)
}
字符串
初始化
/// 字面量定义字符串
var emptyString = ""
/// 初始化器语法定义字符串
var anotherEmptyString = String()
/// isEmpty检查字符串是否为空
if emptyString.isEmpty {
print("emptyString is Empty")
}
多行字面量
- 多行字符串字面量是用三个双引号引起来的一系列字符串
- 多行字符串字面量把所有行包括在引号内,开始和结束默认不会有换行符
- 当你的代码中在多行字符串字面量里包含了换行,那个换行符同样会成为字符串里的值。如果你想要使用换行符来让你的代码易读,却不想让换行符成为字符串的值,那就在那些行的末尾使用反斜杠(\)
- 多行字符串可以缩进以匹配周围的代码。双引号(”“”)前的空格会告诉Swift其他行前应该有多少空白是需要忽略的
let multiString = """
我是第一行
我是第二行
我是第三行
我是第四行
"""
print(multiString)
打印结果:
我是第一行
我是第二行
我是第三行
我是第四行
let multiString = """
我是第一行\
我还是第一行\
我还是第一行\
我还是第一行
"""
print(multiString)
打印结果:[图片上传失败...(image-d4311e-1607090303055)]
我是第一行我还是第一行我还是第一行我还是第一行
特殊字符
- 转义特殊字符\0(空字符),\(反斜杠),\t(水平制表符),\n(换行符),\r(回车符)," (双引号)以及'(单引号)
- 任意的Unicode标量,写作\u{n},里边的n是一个1-8位的16进制数字,其值是合法Unicode值
- 可以在多行字符串字面量中包含双引号(“) 而不需转义。要在多行字符串中包含文本""",转义至少一个双引号
扩展字符串分割符(Raw String)
- 在字符串字面量中放置扩展分隔符来在字符串中包含特殊字符而不让他们真的生效
- 把字符串放在双引号内并有井号(#)包裹
- 如果需要字符串中某个特殊符号的效果,使用匹配你包裹的井号数量的井号并在前面写转义字符\
let str = #"Line 1 \n Line2"#
print(str)
打印结果:
Line 1 \n Line2
let str = #"Line 1\#nLine 2"#
let str1 = ###"Line 1\###nLine 2"###
print(str)
print(str1)
打印结果:
Line 1
Line 2
Line 1
Line 2
字符串的操作
var 指定的可以修改
let 指定的不可修改
var mutable = "abc"
/// 最终的结果:abcdef
mutable += "def"
let notable = "abc"
/// 这是错误的写法,会报错
notable += "def"
字符串是值类型
- String 值在传递给方法或者函数的时候会被复制过去
- 赋值给常量或变量的时候也是一样
- Swift编译器优化了字符串使用的资源,实际上拷贝只会在确实需要的时候才进行
操作字符
- for-in 循环遍历String中的每一个独立的Character
- Character 类型
- String 值可以通过传入Character数组来构造
for character in "abc" {
print(character)
}
打印结果:
a
b
c
let name:[Character] = ["a","b","c","d"]
let nameString = String(name)
print(nameString)
打印结果:
abcd
字符串拼接
- 使用加运算符(+) 创建
新字符串
- 使用加赋值符号(+=) 在已经
存在的String值末尾追加一个String的值
- 使用String类型的
append()
方法来可以给一个String变量的末尾追加Character值
var name = "abc"
var age = "18"
name += "def"
print(name)
var introduction = name + age
print(introduction)
introduction.append("chaozhou")
print(introduction)
打印结果:
abcdef
abcdef18
abcdef18chaozhou
字符串插值
- 每一个插入到字符串字面量的元素都要被
一对圆括号包裹
,然后使用反斜杠前缀
- 要在使用
扩展分隔符的字符串(Raw String)
中使用字符串插值,在反斜杠后使用匹配首尾井号数量的井号
let number = 3
let message = "mine number is \(number)"
let number = 3
let message = #"mine number is \#(number)"#