关于ios:Swift基础语法简化版

7次阅读

共计 11754 个字符,预计需要花费 30 分钟才能阅读完成。

举荐一个学习网站:https://www.cnswift.org

该网站是对 Swift 官网文档的翻译,但不是无脑翻译,而是联合作者的开发教训,在翻译的根底上,给出一些实用的倡议。

常量与变量

在 Swift 中规定,定义一个标识符的时候必须明确阐明该标识符是常量还是变量:

应用 let 来定义常量,定义之后不可批改;

应用 var 来定义变量,定义之后能够批改。

let a: Int = 2a = 3// 会报错,因为 a 是常量,不能够批改
var b: Int = 6b = 8// 失常运行,b 是变量,能够批改 

根本数据类型

Swift 中的根本数据类型包含:整型、浮点型、Bool 型

整型

有符号整型

Int8:有符号 8 位整型

Int16:有符号 16 位整型

Int32:有符号 32 位整型

Int64:有符号 64 位整型

Int:默认,和平台相干,相当于 OC 中的 NSInteger

无符号整型

UInt8:无符号 8 位整型

UInt16:无符号 16 位整型

UInt32:无符号 32 位整型

UInt64:无符号 64 位整型

UInt:默认,和平台相干,相当于 OC 中的 NSUInteger

浮点型

Float:32 位浮点型

Double:64 位浮点型(默认)

Bool 型

true:真

false:假

根本数据类型的运算与 OC 是一样的:

a+b// 加
a-b// 减
a*b// 乘
a/b// 除
a%b// 取余 

a+b// 加 a -b// 减 a *b// 乘 a /b// 除 a%b// 取余然而须要留神的是,在 Swift 中,不同类型的数据是不能够运算的,比方整型和浮点型就不能够一块进行运算:

如果想要运算,那么就要将其中一种类型转为另一种类型:

var c = 1var d = 1.1Double(c)+d 

Swift 中的类型推导

Swift 是一种强类型语言,也就是说,在 Swift 中,任何一个变量或者常量都必须有明确的类型。

var d: Int = 8 

如果在定义一个标识符的时候有间接进行赋值,那么标识符前面 的类型能够省略:

var d = 8 

因为 Swift 有类型推导,会主动依据前面的赋值来决定后面的标识符的数据类型。

咱们能够通过 option+ 鼠标左键来查看变量的数据类型:

须要留神的是,如果一个变量的类型曾经确定了,那么就不能够再给变量赋其余类型的值:

这里的变量 c 曾经是整型了,那么就只能给其赋整型值,不可赋其余类型的值。

运算符

计算运算符

+、-、*、/、%

须要特地留神的是,计算运算符两边的数据类型必须为同一类型,如果类型不同,则编译器会报错。

赋值运算符

=、+=、-=、*=、/=、%=

须要特地留神的是,赋值运算符两边的数据类型必须为同一类型,如果类型不同,则编译器会报错。

比拟运算符

、>=、<、<=、==、!=

须要特地留神的是,比拟运算符两边的数据类型必须为同一类型,如果类型不同,则编译器会报错。

区间运算符

Swift 特有的。

1...8   // 闭区间运算符,示意从 1 到 8(包含 1 和 8)的所有值的区间 1...    // 闭区间运算符,示意从 1 往后有限延长...8    // 闭区间运算符,示意从 8 往前有限延长 1..<8   // 半开区间运算符,示意从 1 到 8(包含 1,然而不包含 8)的所有值的区间..<8    // 半开区间运算符,示意从 8 往前(不包含 8)有限延长 

元组

OC 中没有元组类型,元组是 Swift 中特有的一种数据结构。

元组用于定义一组数据,组成元组的数据能够称为元素。

咱们当初应用元组来形容一个人的信息:

var one = ("Norman", "male", 30, 178.5)print(one.0) 

而后摁住 option 键单击,发现变量 one 的类型如下:

这个类型是依据赋的值倒推进去的。

下面的元组 one 中的元素从左到右一次示意:名字、性别、年龄、身高。人们乍一看,其实还是不晓得每个元素别离代表的意思的,所以为了便于了解,为了可能见文知意,咱们还能够这样来定义元组:

// 给元组中的元素加上名称,之后能够通过元素名称来拜访元素
var one = (name:"Norman", gender:"male", age:30, height:178.5)
print(one.name) 

摁住 option 键单击,发现变量 one 的类型如下:

元组中元素的拜访

// 写法一
let error = (404, "Not Found")
// 下标拜访
print(error.0)
print(error.1)

// 写法二
let error = (errorCode:404, errorInfo:"Not Found")
// 别名拜访
print(error.errorCode)
print(error.errorInfo) 

逻辑分支

分支的介绍

所谓的分支语句,就是 if/switch/ 三目运算符等判断语句。

通过分支语句能够控制程序的执行流程。

if 分支语句

Swift 中的 if 语句和 OC 中的 if 语句还是有区别的:

区别 1:Swift 中判断句能够不加小括号 (),然而判断之后的执行语句必须要用大括号{} 括起来;OC 中判断语句必须加小括号(),如果判断之后的执行语句只有一句话的话能够省略大括号{}。

let g = 8if g>0 {print("负数")} 

区别 2:Swift 的判断句中必须要有明确的虚实,必须要有明确的布尔值,Swift 中不再有非 0 即真的概念;OC 中是非 0 即真、非空即真。

三目运算符

Swift 中的三目运算与 OC 中放弃了统一的格调。

let a = 10;let b = 20;
// 打印较大值 print(a > b ? a : b); 

guard 的应用

guard 语句与 if 语句十分相似,然而与 if 语句不同的是,guard 语句当条件为 false 的时候才会执行 {} 外面的代码

guard 语句必须带有 else 语句,他的语法如下:

  • 当条件表达式为 true 的时候跳过 else 语句的内容,执行前面的语句组;
  • 当条件表达式为 false 的时候执行 else 语句中的内容,跳转语句个别是return、break、continue 或者 throw
guard 条件表达式 else {// 当条件表达式不成立的时候执行的语句  break}
语句组 

另外一个须要阐明的点是,guard 语句必须放在函数中。

func online(age : Int) -> Void {guard age >= 18 else {        print("未成年人不能上网")        return    }    print("能够上网")}
online(age: 17) 

Switch-case 语句

switch 作为抉择语句中必不可少的语句也被退出到了 Swift 中。

首先看一个例子:

/** case 区间 */let a = 100
switch a {case ..<60:    print("不及格")case 60..<80:    print("合格")case 80..<90:    print("良好")case 90...100:    print("优良")default:    print("蠢才")}
/** 一个 case 能够判断多个值,多个值以, 隔开 */let b = 0
switch b {case 0,1:    print("正常人")default:    print("其余")}
/** fallthrough 关键字进行穿透 * 所谓的穿透是指,当这个 case 满足的时候,执行完这个 case 所对应的内容之后,* 不会跳出,而是接着执行紧挨着的下一个 case 所对应的内容 */let c = 0
switch c {case 0:    fallthroughcase 1:    print("正常人")default:    print("其余")}
/** switch 是反对多种数据类型的 * 岂但反对整型、区间,还反对浮点型、字符串等。*/let d = 10let e = 5var result = 0
let opration = "+"
switch opration {case "+":    result = d + ecase "-":    result = d - ecase "*":    result = d * ecase "/":    result = d / edefault:    result = 0} 

Swift 中的 case 前面的语句块执行结束之后能够不跟 break,因为默认会有 break。

循环

在 C /OC 中,常见的循环有 for/while/do-while;在 Swift 中,对应的循环有 for/while/repeat-while。

For 循环

for 循环分为两种,一种是传统的 C 语言格调的 for 循环,如下:

for var i = 0; i < 10; i++ {print(i)} 

这种传统写法,在 Swift3 中曾经被淘汰了,如下:

还有一种是 for-in 循环,如下:

for i in 0..<10 {print(i)} 

对于 for-in 循环,有一个非凡的中央须要留神:如果在某个循环中不须要用到下标 i,那么应用下划线来代替下标,如下所示:

for _ in 0..<10 {print("Swift")} 

不然的话会有如下的正告⚠️:

while 循环和 repeat-while 循环

//while 循环(先判断,再执行)var a = 0
while a < 10 {print(a)    a+=1}
//repeat-while 循环(先执行一次,再判断)var a = 0
repeat {print(a)    a += 1} while a < 0 

Swift 中的 repeat-while 循环与 OC 中的 do-while 循环其实截然不同,都能够保障至多执行一次。

字符串

OC 和 Swift 中的字符串是有区别的:

  • 在 OC 中,字符串类型是 NSString;在 Swift 中,字符串类型是 String。
  • OC 中定义字符串是应用 @””;Swift 中定义字符串是应用 ””。

字符串的定义

// 不可变字符串 let str1 = "不可变字符串"
// 可变字符串 var str2 = "可变字符串"str2 = "我变变变"
// 多行字符串 var str3 = """多行字符串第一行第二行第三行第四行 56""" 

下面介绍了了几种传统的字符串定义模式,接下来咱们来聊聊 Swift5.0 之后新推出的Raw String(原始字符串)

Raw String 是应用 # 来包裹字符串,其最大的特点就是:它 不会对反斜杠进行非凡的本义解决

当字符串中含有双引号或者反斜杠本义符的时候,应用传统的形式定义如下:

let var1 = "如果句子中有双引号"" 就会很难堪 "// 输入:如果句子中有双引号"" 就会很难堪 let var2 = "如果句子中有转义字符就会很难堪"// 输入:如果句子中有转义字符就会很难堪 

应用 Swift5.0 新推出的 RawString 定义如下:

let var1 = #"如果句子中有双引号"" 就会很难堪 "#let var2 = #" 如果句子中有转义字符就会很难堪 "# 

如果字符串是被 #包裹,那么 是不须要本义的

那如果字符串中有 #,那怎么办呢?答案是应用两个井号## 来包裹:

let var1 = ##"如果句子中有井号 #"##// 打印后果:如果句子中有井号# 

字符串的罕用操作

// 计算字符串的长度
let str = "12345678"
print(str.count)
print((str as NSString).length)

// 拼接两个字符串
var str1 = "Norman" + "Lee"
var str2 = str1.appending("666")

// 遍历字符串(字符串能够看成是多个字符的汇合)let str = "abcdefg"
for char in str {print(char)
}

// 字符串中是否蕴含某子字符串
let str = "abcdefg"
print(str.contains("abc")) //true
print(str.contains("A")) //false
print(str.contains("h")) //false

// 宰割字符串
let str = "abc&def&ghi&jkl&mn"
let desc = str.components(separatedBy: "&") // ["abc", "def", "ghi", "jkl", "mn"]
for item in desc {print(item)
}

// 字符串替换
let str = "abc&def&ghi&jkl&mn"
let result = str.replacingOccurrences(of: "&", with: "---")
print(result) // abc---def---ghi---jkl---mn 

数组

数组是一堆 有序 的由 雷同类型的元素 形成的 汇合。

数组中的元素是有序的,能够反复呈现

Swift 用 Array 示意数组,它是一个 泛型汇合

数组的初始化

数组分为 可变数组和不可变数组

// 定义一个可变数组
var arrar1 : [String] = [String]() // 此时定义的是一个空数组

// 定义一个不可变数组
let array2 : [String] = ["Norman", "Lavie"] 

申明一个 Array 类型有如下两种写法,能够任选其一:

// 语法糖 var array1 : [String]
var array2 : Array<String> 

申明的数组须要进行初始化能力应用,数组类型往往是在申明的同时进行初始化的:

// 定义的同时间接进行初始化
var array1 = ["Norman", "Lavie"]

// 先定义,而后初始化
var array2 : Array<String> array2 = ["Norman", "Lavie"] 

留神辨别 <u >数组和元组</u>。

数组的基本操作

var array = ["Norman", "Lavie", "绪雨成澜"]

// 获取长度
array.count // 3

// 判空
array.isEmpty // false

// 尾部增加元素
array.append("大鱼") // ["Norman", "Lavie", "绪雨成澜", "大鱼"]

// 指定地位插入元素
array.insert("Bruce", at: 1) // ["Norman", "Bruce", "Lavie", "绪雨成澜", "大鱼"]

// 删除元素
array.remove(at: 0)
array.removeLast()
array.removeFirst()

// 批改元素
array[0] = "小李"

// 取值(间接通过下标索引取值)print(array[0])
print(array[1])

// 倒序
array.reverse() 

数组的遍历

var array = ["Norman", "Lavie", "绪雨成澜", "大鱼"]

//for-in 遍历下标
for i in 0..<array.count {print(array[i])
}

//for-in 遍历元素
for name in array {print(name)
}

// 遍历某区间内的元素
for name in array[0...2] {[print(name)]
}

// 元组形式的遍历(如果既须要拿到索引又须要拿到元素,举荐应用该形式)
for (index, name) in array.enumerated() {print(index)
    print(name)
} 

数组的合并

var array1 = ["Norman", "Lavie"]
var array2 = ["绪雨成澜", "大鱼"]
array1 += array2
print(array1) // ["Norman", "Lavie", "绪雨成澜", "大鱼"] 

尽管仅仅用一个加号就能够实现数组的合并,然而肯定要保障一点:要合并的两个或者多个数组的 元素类型必须要保持一致

字典

字典是由 键值对(key:value)组成的汇合,它由两局部汇合形成:一个是键汇合,一个是值汇合。字典是通过拜访键来间接拜访值的,键汇合中是不能够有反复元素的,而值汇合中的元素是能够反复的。

字典中的元素是 无序 的。

Swift 中的字典类型是 Dictionary,是一个 泛型汇合

字典的初始化

在 Swift 中,应用 let 润饰的字典是不可变字典,应用 var 润饰的字典是可变字典:

// 定义一个可变字典
var dic1 : [String : Any] = [String : Any]()

// 定义一个不可变字典
let dic2 : [String : Any] = ["name" : "Norman", "age" : 28] 

在申明一个字典的时候,有上面两种形式,能够任选其一:

var dic : [String : Any]
var dic : Dictionary<String, Any> 

跟数组一样,申明的字典也是须要初始化之后能力应用:

// 申明的同时进行初始化
var dic1 : [String : Any] = [String : Any]()

// 先申明,后初始化
var dic : Dictionary<String, Any>
dic = ["name" : "Norman", "age" : 28] 

额定说一点,在 Swift 中,任意类型是应用 Any 来示意 的。

字典的基本操作

var dict : [String : Any] = ["name" : "Lavie", "age" : 18, "gender" : "male"]

// 长度
print(dict.count)

// 判空
print(dict.isEmpty)

// 增加元素
dict["height"] = 178
dict["weight"] = 65

/*
 * 须要留神的是,下面增加元素的这种形式,如果 Key 值不存在,那么就是增加元素;* 如果 Key 值存在,那么就是批改元素
 */

// 删除元素
dict.removeValue(forKey: "age") // 删除指定元素
dict.removeAll() // 删除所有元素

// 批改字典
dict["name"] = "Norman" // 形式一
dict.updateValue("大鱼", forKey: "name") // 形式二

// 查问字典
print(dict["name"]) 

字典的遍历

var dict : [String : Any] = ["name" : "Lavie", "age" : 18, "gender" : "male"]

// 遍历字典中所有的 Value 值
for value in dict.values {print(value)
}

// 遍历字典中所有的 Key 值
for key in dict.keys {print(key)
}

// 遍历所有的键值对
for (key, value) in dict {print(key)
    print(value)
} 

字典的合并

后面讲的字符串和数组,都是能够间接应用加号 + 来进行合并的,然而这一点对于字典并不实用。字典是不能够间接应用加号 + 来进行合并的。

字典应该应用如下形式来合并:

var dict1 : [String : Any] = ["name" : "Lavie", "age" : 18, "gender" : "male"]var dict2 : [String : Any] = ["height" : 178, "weight" : 65]for (key, value) in dict2 {dict1[key] = value}print(dict1) // ["gender": "male", "age": 18, "weight": 65, "height": 178, "name": "Lavie"] 

然而这种合并字典的形式须要特地留神,如果有 Key 重名,那么该 Key 在原字典中所对应的 Value 值将被新字典中所对应的 Value 值笼罩。

可选型

在 OC 中,如果一个变量临时不应用,能够赋值为 0(根本数据类型)或者赋值为 nil(对象类型)。在 OC 中,nil 就示意一个空指针,它并不作为一个非凡的类型。

在 Swift 中,nil 是一个非凡的类型,它与 Int、String 一样,都是一种类型。并且Swift 语言又是一种强类型语言,因而不能间接将 nil 赋值给其余类型的数据。

在开发中,碰到 nil 在劫难逃,因而 Swift 推出了可选类型。

可选类型的取值有如下两种:

  • 无值的状况下——nil
  • 有值的状况下——失常取值

定义可选类型

// 写法一:官网定义形式
var a : Optional<Int> = 6 // 有值
a = nil // nil

// 写法二:语法糖(间接在类型前面加问号?)var b : Int? = 8 // 有值
b = nil // nil 

可选类型的应用

给可选类型赋值:

// 定义可选类型
var name : String? = nil

// 给可选类型赋值
name = 123 // ❌谬误写法,可选类型也是有类型校验的,这里只能复制字符串,赋值其余类型都会报错
name = "norman" // 正确

// 打印后果
print(name) // Optional("norman")  因为是可选类型,所以会带 Optional 

取出可选类型的值(显性解包):

// 定义可选类型
var name : String? = "Norman"

print(name) // Optional("norman")

// 取出可选类型的实在值
// 应用!强制解包(显性解包)print(name!) // Norman

// 如果可选类型为 nil,强制解包会出错
name = nil
//print(name!) // 报错:Unexpectedly found nil while unwrapping an Optional value

// 正确写法应该先判空
if name != nil {print(name!)
} 

取出可选类型的值(隐式解包):

Swift 中有一个if-let 写法,if-let 就是专门用于做可选绑定(隐式解包)的,如下:

if let 常量 = 可选型 {// 解决常量} 

这里的【常量 = 可选型】语句的作用是:如果可选型的值不是 nil,那么就将可选型的实在值传给常量,并且执行花括号 {} 外面的语句;如果可选型的值是 nil,那么【常量 = 可选型】这个条件就不成立(因为不能间接给一个非可选型变量赋值为 nil),那么就不会走到花括号外面的内容。

// 定义可选类型
var name : String? = "Norman"

/*
 * 可选绑定(隐式解包)*/
if let nameString = name {print(nameString)
} 

强烈推荐应用可选绑定来对可选型进行隐式解包

类型转换

根底数据类型转换

比方 Double 转 Int,Int 转 Float 等,只须要应用数据类型 (待转类型) 即可:

//Int 转 Double
var a : Int = 6
var b : Double = Double(a)

//Float 转 Int
var c : Float = 8.99
var d : Int = Int(c) 

根底类型与字符串转换

// 字符串插值能够间接将根底类型转换成字符串
var age : Int = 6
var str = "小明往年 (age) 岁了"

// 字符串转成根本类型,必须要保障字符串的内容是能够转换的
var string = "123"
var d = Int(string) 

函数

Swift 中的函数,其实就相当于 Objective- C 中的办法。函数的格局如下:

func 函数名(参数, 列表)  -> 返回值类型 {代码块    return 返回值} 

有以下几点阐明:

1,func 是定义函数的关键字

2,参数列表中的多个参数之间,能够应用英文逗号 , 宰割,也能够没有参数

3,应用 -> 指向返回值类型

4,如果函数没有返回值,则 -> 返回值类型 局部能够省略

常见的函数类型

没有参数,没有返回值:

// 写法一:官网规范写法
func drinkWater() -> Void {print("drink water 111")
}

// 写法二:如果没有返回值,Void 能够写成()
func drinkWater1() -> () {print("drink water 222")
}

// 写法三:如果没有返回值,前面的内容能够都不写
func drinkWater2() {print("drink water 333")
}

// 调用函数
drinkWater()
drinkWater1()
drinkWater2() 

有参数,没有返回值:

func call(phoneNumber : String) {print("退出 iOS 交换群(phoneNumber)")}call(phoneNumber: "642363427") 

没有参数,有返回值:

func myName() -> String {    return "norman"}let name = myName() 

有参数,有返回值:

func plus(a : Int, b : Int) -> Int {return a + b;}let result = plus(a: 3, b: 3) 

函数的应用留神

1,每一个函数的形式参数都蕴含形式参数标签和形式参数名两局部

  • 形式参数标签用在调用函数的时候
  • 形式参数名用在函数的实现当中
  • 在调用函数的时候,每一个形式参数前边都会有一个形式参数标签
  • 默认状况下,形式参数应用它们的形式参数名作为形式参数标签
  • 如果不想要形式参数标签,能够在形式参数名称前加上 _
// 这里的 info1 和 info2 就是形式参数标签
//name 和 age 是形式参数名称
func personalInfo(info1 name : String, info2 age : Int) {
    // 在函数的实现中应用形式参数名称
    print("姓名:(name),年龄:(age)")
}
// 在函数调用的时候应用形式参数标签
personalInfo(info1: "norman", info2: 23)

// 上面是默认写法
// 此时,name 和 age 既是形式参数标签,也是形式参数名称
func personalInfo(name : String, age : Int) {
    // 在函数外部实现的时候,name 和 age 是形式参数名称
    print("姓名:(name),年龄:(age)")
}
// 在函数调用的时候,name 和 age 是形式参数标签
personalInfo(name: "norman", age: 24)

// 如果不想要形式参数标签,能够在形式参数名称后面加 _
func personalInfo(_ name : String, _ age : Int) {print("姓名:(name),年龄:(age)")
}
// 在函数调用的时候,没有形式参数标签
personalInfo("norman", 24) 

2,能够给函数的参数设置默认值

// 如果不想要形式参数标签,能够在形式参数名称后面加 _
func personalInfo(_ name : String = "lavie", _ age : Int = 28) {print("姓名:(name),年龄:(age)")
}

personalInfo() // 姓名:lavie,年龄:28
personalInfo("norman", 24) // 姓名:norman,年龄:24 

3,指针的传递

默认状况下,函数的参数是值传递。如果想扭转里面的变量,则须要传递变量的地址。

// 替换值
func swapInt(a : inout Int, b : inout Int) {
    let temp = a
    a = b
    b = temp
}

var a = 6
var b = 8
print("a=(a), b=(b)") // a=6, b=8
swap(&a, &b) // 将地址传递进来
print("a=(a), b=(b)") // a=8, b=6 

函数的类型

咱们之前介绍的数组 Array、字典 Dictionary 等,都是 值类型 ,而函数是 援用类型

每个函数都有属于本人的类型,一个函数的类型是由该函数的 参数类型 返回类型 决定的。

有了函数类型当前,就能够把函数类型像 Int、Array 一样来应用了。

上面的例子定义了 additionMethod 和 multiplicationMethod 两个函数,这两个函数都传入了两个 Int 类型的参数,返回一个 Int 类型值,因而这两个函数的类型都是(Int, Int) -> Int

func additionMethod(a : Int, b : Int) -> Int {return a + b;}
func multiplicationMethod(a : Int, b : Int) -> Int {return a * b;} 

接下来咱们来看一下函数的简略赋值:

// 初始化一个函数类型变量,并赋初始值
var mathMethod = additionMethod
mathMethod(2, 3) // 5
// 给函数类型变量赋其余值
mathMethod = multiplicationMethod
mathMethod(2, 3) // 6 

函数也能够作为一个函数的参数:

func additionMethod(a : Int, b : Int) -> Int {return a + b;}

func multiplicationMethod(a : Int, b : Int) -> Int {return a * b;}

// 函数作为参数
func printResult(a : Int, b : Int, mathMethod : (Int, Int) -> Int) {print(mathMethod(a, b))
}

printResult(a: 3, b: 4, mathMethod: additionMethod) // 7
printResult(a: 3, b: 4, mathMethod: multiplicationMethod) // 12 

函数还能够作为一个函数的返回值:

func additionMethod(a : Int, b : Int) -> Int {return a + b;}

func multiplicationMethod(a : Int, b : Int) -> Int {return a * b;}

// 函数作为返回值
func mathMethod(a : Int) -> (Int, Int)->Int {
    if a > 10 {return additionMethod}
    return multiplicationMethod
}

var resultMethod = mathMethod(a: 11)
resultMethod(6, 8) // 14 

举荐文章

  • Swift 学习笔记
  • Swift 学习总结
  • 【Swift 实现代码】iOS 架构模式之 MVP
正文完
 0