上一篇中学习了基本类型和基本语法后,这一篇主要记录一下有关字符串,数组,字典等数据结构的使用方式。
字符串
在swift中,字符串同样也分为可变字符串和不可变字符串
1.不可变字符串的创建
let str = "hello world"
let关键字下的字符串都是不可变的,不能重新赋值
2.求字符串长度
let length = str.characters.count
与oc不同,swift中没有length方法来获取长度,但可以通过获取原串的总数来获取长度。
3.字符串格式化
let name = "zzq"
let age = 25
let height = 180
let infoStr = "name = \(name) age = \(age) height = \(height)"
在swift中,拼接字符串不需要使用oc那样的format方式,采用(xxx)的格式就可以把外部变量传入字符串中了
let min = 3
let second = 12
let timeStr = String(format:"%02d:%02d",min,second)
对于数字类型,我们也可以使用format方式进行格式设定
4.字符串截取
let urlString = "www.baidu.com"
let header = (urlString as NSString).substring(to: 3)
let middle = (urlString as NSString).substring(with: NSMakeRange(4, 5))
let footer = (urlString as NSString).substring(from: 10)
在swift中截取字符串可以将String类型先转换成NSString
类型,再通过NSString
中提供的API进行截取。
5.字符串拼接
let str1 = "aaa"
let str2 = "bbb"
let str3 = str1 + str2
在swift中,我们可以直接使用 + 方法拼接多个字符串
数组Array
与oc相同,数组也分为可变与不可变数组
1.不可变数组的声明
声明指定类型的数组
方式一、
let array : Array<String> = ["aa","bb","cc"]
方式二、
let array : [String] = ["aa","bb","cc"]
声明任意类型的数组
let array : Any = ["aa","bb",123]
可以通过Any关键字告诉编译器数组中内容类型是任意的
2.可变数组的声明
方式一、
var array = Array<String>()
方式二、
var array = [String]()
3.可变数组的操作
1>添加---append
array.append("1")
array.append("2")
array.append("3")
2>移除--remove
//移除所有元素
array.removeAll()
//移除指定位置的
array.remove(at: 0)
//移除第一个
array.removeFirst()
//移除最后一个
array.removeLast()
3>修改
array[0] = "zzq"
4>遍历
方式一,通过下标遍历数组
for i in 0..<arrayM.count {
print(arrayM[i])
}
方式二,直接获取数组中的元素
for item in arrayM {
print(item)
}
方式三,通过枚举方式遍历
for (index, item) in arrayM.enumerated() {
print(index)
print(item)
}
4.数组的合并
let array1 : [String] = ["aa","bb"]
let array2 : [String] = ["test","1","2"]
let array 3= array1 + array2
与字符串类似,相同类型的数字也可以通过 + 直接合并
字典Dictionary
初始化不可变字典
方式一、
let dict : Dictionary<String,Any> = ["key1":"1","key2":2]
方式二、
var dict1 = ["key1":1,"key2":"2","key3":3] as [String:Any]
方式三、
let dict2 : [String : Any] = ["key1":"value","key2":123,"key3":"str"]
注意的是,在初始化字典的时候需要指定value的类型
初始化可变字典
var dictM = [String:Any]()
var dictM1 = Dictionary<String, Any>()
操作可变字典
1>添加
与oc一样,直接设置key-value,如果字典中没有这个key,则添加
let dict = [String : Any] ()
dict["name"] = "zzq"
dict["age"] = 22
dict["height"] = 181
2>移除
dict.removeValue(forKey: "age")
3.修改
方式一、同上,当存在该key时,更新key对应的value
dict["name"] = "zzq"
方式二、通过updateValue函数进行更新,效果与方式一一样。
dict.updateValue("zzq", forKey: "name")
遍历字典
//遍历key
for key in dict.keys {
print(key)
}
//遍历value
for value in dict.values {
print(value)
}
//遍历key-value
for (key,value) in dict {
print(key,value)
}
合并字典
与字符串,数组不同,字典不能通过 + 来进行合并,需要手动遍历添加
var dict1 = ["1":1,"2":"2","3":2] as [String:Any]
let dict2 : [String : Any] = ["name":"zhu","age":25,"height":181]
for (key,value) in dict2 {
dict1[key] = value
}
将不可变字典dict2中的键值对,添加进可变字典dict1中,如果dict1中有相同key的键值对,则会将dict1中该key的value覆盖
元组
同样是数据集合,与数组,字典不同的是,元祖可以直接获取value的类型。先来看看数组和字典,当我们需要获取一个字符串,并打印它的长度时
//对比数组
let infoArr : [Any] = ["name",18,181]
let arrname = infoArr[0] as! String
print(arrname.characters.count)
//对比字典
let infodict : [String : Any] = ["name":"zzq","age":22,"sex":1]
let dictName = infodict["name"] as! String
我们可以看到,对于Any类型的集合,即使获取一个string类型的变量,也必须先转换一次才能进行操作。再看看元组
下标获取
let infoTuple = ("zzq",22,111,181)
let tupleName = infoTuple.0
这个时候获取的就已经是字符串类型了
键值对获取
let infoTuple1 = (name : "mingzi",age : 12,text : "asd",num : 222)
let name = infoTuple1.name
let text = infoTuple1.text
let num = infoTuple1.num
print(nameT.characters.count) //可以直接打印 打印结果6
直接构造元组结构
let (nameT, ageT, heightT) = ("zzq",25,181)
let name = nameT
let age = ageT
let height = heightT
print(nameT.characters.count) //可以直接打印 打印结果3
可选类型
使用可选类型主要是为了再处理空的情况下,可以更严谨的判断。并且在swift中只有可选类型才能赋值为nil,其他类型不能赋值为nil
1.声明可选类型变量
//1>普通
var name : Optional<String> = nil;
//2>语法糖
var name : String? = nil
可以使用Optional关键字声明,也可以通过swift语法糖进行声明
2.可选类型赋值
//1>
name = Optional("what")
//2>
name = "hehehe"
同样可以使用Optional关键字来赋值,或者直接赋值由编译器进行判断
3.取出可选类型的值
对于可选类型,我们不能直接使用,而需要对它进行解包
1>强制解包,格式:变量!
name是一个可选类型的字符串
print(name!)
需要注意的是,如果可选类型为nil,强制解包会导致崩溃
2>可选绑定(固定格式if let)
if let tempname = name {
print(tempname)
}
如果name不为nil,则解包到临时变量中,并执行括弧内的代码,如果name=nil则不解包,不执行括弧内代码。
4.可选类型应用场景
//字符串转int
let str = "123"
let num : Int? = Int(str)//123/nil
//根据文件吗获取文件路径
let path :String? = Bundle.main.path(forResource: "123.plist", ofType: nil) //string/nil
//将字符串转NSURL
//若字符串有中文,返回url/nil
let url : NSURL? = NSURL(string:"www.baidu.com")
//从字典中取出元素
let dict : [String : Any] = ["name":"zzq","age":11]
let value = dict["name"] //Any/nil
开发中遇到可选类型的地方很多,对于可能出现nil的地方都要使用可选类型进行检查。
类型转换
1.通过as?转换为可选类型
//Any类型的value不能直接使用
let dict = ["name":"zzq","age":19,"height":1.81] as [String : Any]
//通过as?进行转换
if let name = dict["name"] as? String {
print(name)
}
注意:系统会自动判断tempName是否可以转成String,如果转化不成功则返回nil
2.通过as!转换为指定类型
let dict = ["name":"zzq","age":19,"height":1.81] as [String : Any]
let tempname = dict["name"]
let name = tempname as! String
通过as!转具体类型,转换失败程序直接崩溃
函数
swift中函数的声明
func 函数名(参数)-> 返回类型 {
代码块
return 返回值
}
构造不同类型的几种函数
1.无参数,无返回值
func test() {
print("test")
}
无返回值也可以加上->void ,表示返回值类型为void
2.有参数,无返回值
func testWithParams(param : String) {
print(param)
}
参数的格式是 参数名 :类型
3.无参数,有返回值
func testForReturn() -> String {
return "测试返回值"
}
4.有参数,有返回值
func sum(num1 : Int , num2 : Int) -> Int {
return num1 + num2
}
另外几种参数的定义方式
1.外部参数
当我们希望给参数取别名时,我们可以设置外部参数名
func sum(canshu1 num1 : Int, canshu2 num2 : Int) {
}
//调用时显示
sum(canshu1: 1, canshu2: 2)
在变量名前添加外部变量名 ,这是看到的提示就不是num1而是用canshu1代替
2.隐藏外部参数
func add(_ num1 : Int, _ num2 : Int) {
}
//调用时显示
add(1, 2)
在参数名前添加 _ ,这是调用时就可以隐藏外部变量参数了。
3.可变参数
func change(nums : Int...) -> Int {
var total = 0
for n in nums {
total += n
}
return total
}
调用显示
change(nums: 1,2,3,4,5)
在类型后添加...,参数将变为一个数组类型,我们可以通过遍历数组的方式查看传入的具体参数。
4.默认参数值
func makeDefualt(name : String = "默认") ->String {
return name;
}
//调用时可不传参数
makeDefualt()
在类型后添加 = 值 ,可以指定参数的默认值。当不传入该参数时,使用默认值。
5.指针参数
在swift中,函数内不能直接修改参数变量
var m : Int = 20
var n : Int = 30
func myswap(num1 : Int,num2 : Int) {
let temp = num1
num1 = num2
num2 = temp
}
上面是一个错误的例子,编译器会说num1.num2是let类型的,不允许修改,我们可以使用临时变量获取参数的值,但这样代码会变得恶心。
//指针参数
var m : Int = 20
var n : Int = 30
func myswap(num1 :inout Int,num2 :inout Int) {
let temp = num1
num1 = num2
num2 = temp
}
myswap(num1: &m, num2: &n)
print("m:\(m),n:\(n)")
打印结果:m:30,n:20
在: 与 类型中间,使用inout关键字可以传入参数的地址。这样我们就可以直接对传入参数进行修改。