Swift 5.1 基础学习--- 概念整理手册01

242 阅读10分钟

声明:因为是基础,所以很多内容和网站的大同小异,这只是本人记录学习记录而已

1. 声明常量和变量

  • 使用 let 关键字声明一个常量
let test:Double = 2.0
// test = 3.0 // 该操作无法成立,因为常量不能重新赋值
  • 使用 var 关键字声明一个变量
var test2 : Int = 1
test2 = 5 // 这样是可以的,因为可以给一个变量重新赋值

2. 数值类型转换

let testInt = 3
let testDouble = 5.0
//let sum = testInt + testDouble // 方法错误,类型不匹配,Swift不像Object-c 会自动隐性转换,最好是用显式的方法去明确转换意图

// 使用显式的方法来防止隐藏的转换错误 并有助于明确类型的转换意图
let sum = Double(testInt) + testDouble // 这样就可以了,两个值都是相同类型的

###3. 字符串

  • 使用字符串字面量来初始化一个常量或变量
let testStr = "This is my World!"
  • 使用多行字符串字面量来跨越多行
let testWorldStr = """
原来我只是突然累了 原来我不说了 原来我撑着撑到麻了 原来我不爱了
"""
  • 空字符串
let emptytring = "" // 使用字符串字面量
let otherEmptyString = String() // 初始化语法
  • 修改字符串,添加字符串
// 修改字符串,添加字符串
var modifyStr = "Hello,"
modifyStr += "World!"
  • 字符串插值
print("modifyStr: \(modifyStr)”)// 插入一个字符串
print("sum: \(sum)”)     // 插入一个 Double 值

4. 元组(元组是 Swift中唯一的一种复合类型,可以指定有限个数的任何类型一次整理为一个对象,元组中的每种类型都可以是任何的结构体,枚举或类类型,甚至可以是一个元组或空元组。元组中的每个元素我们称之为一个”分量")

  • 将多个值组合为一个复合值
let httpError = (503,"Server Error")
print("httpError:\(httpError)")
  • 分解元组内容
let (code,reason) = httpError
print("code:\(code)  reason:\(reason)”)

// 另外一种分解方法
let codeByIndex = httpError.0
let reasonByIndex = httpError.1
print("codeByIndex:\(codeByIndex)  reasonByIndex:\(reasonByIndex)")
  • 使用 _ 来忽略元组的某些部分
let (_,justTheReason) = httpError
print("justTheReason:\(justTheReason)")

5. 可选项

  • catchphrase 可以包含 String 或 nil
var catchphrase : String? // 编译器自动设置为nil
catchphrase = "原来我只是突然累了 原来我不说了"
  • 强制解包操作符 (!)
// 如果 catchphrase 不是 nil,count1 包含 catchphrase 的计数值; 否则程序崩溃
let count1 : Int = catchphrase!.count
print("count1: \(count1)")
  • 可选绑定
// 如果 catchphrase?.count 返回的可选Int包含一个值,则将一个称为: count 的新常量设置为可选中包含的值
if let count = catchphrase?.count {
    print("count:\(count)")
}
  • 合并操作符(??)
// 如果 catchphrase 不是 nil,count2 包含 catchphrase 的 count 值;否则为 0
let count2 : Int = catchphrase?.count ?? 0
print("count2:\(count2)")
  • 链式操作符(?)
// 如果 catchphrase 不是nil,count3 包含 catchphrase 的 count 值;否则为 nil
let count3 : Int? = catchphrase?.count
print("count3: \(String(describing: count3))")
  • 隐式展开的可选值
let testCatchphrase : String!  = "原来我只是突然累了 原来我不说了"
let implicitInCatchphrase = testCatchphrase // 无需感叹号
print("testCatchphrase:\(String(describing: testCatchphrase))    implicitInCatchphrase:\(String(describing: implicitInCatchphrase))")

6.集合类型:Array 可以理解为数组

let strArray:[String] = ["One","Two"]
print("strArray:\(strArray)")
// varStrArray 的类型为 [String]
var varStrArray = ["Three","Four"]
print("varStrArray:\(varStrArray)")
  • 测试包含关系
let isFive  = strArray.contains("Five") // 判断是否Array集合里面包含"Five”, 有包含返回 true, 没包含返回 false
let name:String = strArray[0] // 通过索引访问
print("isFive:\(isFive)  name:\(name)")
  • 在列表中修改项目
// 如果索引越界,则会崩溃
varStrArray[1] = "Six"
// strArray[1] = "Six"  // 错误:不能修改,因为是常量
varStrArray.append("Seven") // 添加项目
varStrArray.insert("Eight", at: 1) // 在指定的索引处添加项目
print("新增varStrArray:\(varStrArray)”)
// 不能重新赋值一个常量集合或修改它的内容
// 可以重新赋值一个可变集合和修改它的w内容
varStrArray = ["Nine","Ten","Eleven"]
print("修改varStrArray:\(varStrArray)")
varStrArray[0] = "Twelve"
print("修改0varStrArray:\(varStrArray)")
  • 通过索引来删除
let removeArray = varStrArray.remove(at: 0)
print("removeArray:\(removeArray)   \nvarStrArray:\(varStrArray)")

7. 集合类型: Dictionary 字典

let peopleDictionary : [String : String] = ["Name":"CWJ","Say":"Love"]
print("peopleDictionary:\(peopleDictionary)")
// peopleVarDictionary 的类型为 [String : String]
var peopleVarDictionary = ["Name":"ZBC","Feel":"Perplexed"]
print("peopleVarDictionary:\(peopleVarDictionary)")
  • 通过 key 来访问,如果不存在对应的 key,则返回 nil
let name2 : String? = peopleDictionary["Name"]
print("name2:\(String(describing: name2))")
  • 更新 key 对应的 value
peopleVarDictionary["Name"] = "BC"
print("peopleVarDictionary:\(peopleVarDictionary)")
  • 添加新的 key-value
peopleVarDictionary["Address"] = "HF"
print("peopleVarDictionary:\(peopleVarDictionary)")
  • 通过 key 来删除项目,如果 key 不存在,则返回 nil
let removeDictionary:String? = peopleVarDictionary.removeValue(forKey: "Address")
print("removeDictionary:\(String(describing: removeDictionary))  \npeopleVarDictionary:\(peopleVarDictionary)")
  • 通过下标删除元素,offsetBy是第几个元素, peopleVarDictionary.index(peopleVarDictionary.startIndex, offsetBy: 1) 获取 peopleVarDictionary 里面的下标, startIndex 开始下标 offsetBy是第几个元素
let remove2Dictionary = peopleVarDictionary.remove(at: peopleVarDictionary.index(peopleVarDictionary.startIndex, offsetBy: 1))
print("remove2Dictionary:\(String(describing: remove2Dictionary))  \npeopleVarDictionary:\(peopleVarDictionary)")

8. 集合类型: Set 可以理解为另类的数组,保存的类型不能重复,无序的

  • Set 会忽略重复项,所以 immutableSet 只有 2 项:"QL" 和 "GS" varSet 也只有2项 :"button" 和 "Lab"
let immutableSet : Set = ["QL","GS","QL"]
var varSet : Set = ["button","Lab","button"]
print("immutableSet:\(immutableSet) varSet:\(varSet)")
  • 测试包含关系
let containsStr = immutableSet.contains("QL")
print("containsStr: \(containsStr)")
  • 添加项目
varSet.insert("TableView")
print("varSet:\(varSet)")
  • 移除项目,如果没有找到项目,则返回 nil
let removeVarSet : String? = varSet.remove("TableView")
print("removeVarSet:\(String(describing: removeVarSet))  varSet:\(varSet)")
  • 通过下标删除元素,offsetBy是第几个元素,varSet.index(varSet.startIndex, offsetBy: 1) 获取 varSet 里面的下标, startIndex 开始下标 offsetBy是第几个元素
let removeSet : String? = varSet.remove(at: varSet.index(varSet.startIndex, offsetBy: 1))
print("removeSet\(String(describing: removeSet))   varSet:\(varSet)")
  • 删除所有元素
varSet.removeAll()
print("varSet:\(varSet)")

9. 控制流:循环

  • 遍历一个列表或集合
let listArray : [String] = ["CWJ","L","O","V","E","ZBC"]
   for  str in listArray {
        print("array-str:\(str)")
}
  • 遍历字典
let listDic : [String : String] = ["name":"CWJ","Say":"Love"]
for (key,value) in listDic {
        print("Dictionary-key:\(key)   value:\(value)")
}
  • 遍历范围
  • 1.闭区间操作符(...)
for i in 0...5 {
       print("闭区间-i:\(i)")
}
  • 2.半开区间操作符(..<)
for i in 5..<10 {
      print("半开区间-i:\(i)")
}
  • while
var x = 0
while x < 10 {
      x += 1
      print("while-x:\(x)")
}
  • repeat-while : 判断表达式先走一遍,也就是 while 先走一遍,如果符合就走 repeat 里面的代码。不符合就直接结束
var y = 5
repeat{
       y -= 1
     print("repeat-while-y:\(y)")
}while(y > 2)

10.控制流:条件语句

  • 使用 if 来选择不同路径
let ifNumber = 23
if ifNumber <= 10 {
      // 如果 ifNumber <= 10,就会执行这里面的代码
      print("if-ifNumber: \(ifNumber) 小于等于10")
}else if(ifNumber > 10 && ifNumber < 20){
      // 如果 ifNumber > 10 且小于 20 时,就会执行这里面的代码
      print("if-ifNumber: \(ifNumber) 大于10 小于20")
}else{
      // 如果 ifNumber >= 20,就会执行这里面的代码,也可以说是上面的判断表达式都不成立时,才走这里
      print("if-ifNumber: \(ifNumber) 大于等于20")
}
  • 三元操作符
// if-else条件的简写
let ternaryNumber = 20
let isTall = ternaryNumber > 30 ? true : false
    print("ternaryNumber-isTall: \(isTall)")
  • 如果不满足一个或多个条件,请使用 guard 将程序控制权转移出一个范围 n % 2 == 0 n除以2的余数为0
for n in 0...20 {
   guard n % 2 == 0 else {
   continue
}
   print("guard-n:\(n)")
}
  • 使用 switch 来选择不同路径
let value = 10
switch value {
    case 5:
         // 如果参数为 5,执行这里面的代码
         print("switch-value:\(value)")
    case 10:
         // 如果参数为 10,执行这里面的代码
         print("switch-value:\(value)")
    case 15:
          // 如果参数为 15,执行这里面的代码
          print("switch-value:\(value)")
    case 20:
          // 如果参数为 20,执行这里面的代码
          print("switch-value:\(value)")
    default:
          // 如果参数上面都没有,则执行这里的代码
          print("switch-value:\(value)")
}

11. 函数

func testFunction(){
        //返回 Void 的函数
        hellow()
        // 带参数的函数
        sayHellow(name: "BC")
        // 带默认参数值的函数
        sayHellowStr()
        // 混合默认值的参数和常规参数的函数
        sayHellowAge(age: 30)  // 只使用非默认值参数调用
        // 带参数和返回值的函数
        let num = calculateNum(num1: 20, num2: 30)
        print("num:\(num)")
        // 如果函数只有一个表达式,则可以省略 return
        let number = calculateNumber(num1: 50, num2: 60)
        print("number:\(number)")
        // 指定参数的 label
        let numAdd = add(num1: 20, num2: 20);
        print("numAdd:\(numAdd)")
        // 省略一些参数的参数 label
        let numberAdd = addNumber(10, 10)
        print("numberAdd:\(numberAdd)")
        
        // 接受函数作为参数的函数
        /// - Parameters:
        ///   - addNumbe: 自定义的一个函数,需要有存在的函数
        ///   - num1: 输入的参数1
        ///   - num2: 输入的参数2
        let day = funcContains(addNumbe: add(num1:num2:), num1: 10, num2: 13)
        print("day:\(day)")
        
        
    }
  • 返回 Void 的函数
// MARK:函数- 返回 Void 的函数
func hellow(){
    print("Hellow")
}
  • 带参数的函数
// MARK:函数- 带参数的函数
func sayHellow(name:String){
   print("\(name),你好啊");
}
  • 带默认参数值的函数
// MARK:函数- 带默认参数值的函数
func sayHellowStr(name:String = "ZBC"){
    print("\(name),你好啊");
}
  • 混合默认值的参数和常规参数的函数
// MARK:函数- 混合默认值的参数和常规参数的函数
func sayHellowAge(name: String = "Jason", age:Int){
    print("\(name),你今年\(age)岁啦")
}
  • 带参数和返回值的函数
// MARK:函数- 带参数和返回值的函数
func calculateNum(num1 : Int , num2 : Int) -> Int {
    return num1 + num2
}
  • 如果函数只有一个表达式,则可以省略 return
// MARK:函数- 如果函数只有一个表达式,则可以省略 return
func calculateNumber(num1 : Int,num2 : Int) -> Int{
    num1 + num2
}

-指定参数的 label

// MARK:函数- 指定参数的 label
func add(num1 Num1:Int, num2 Num2:Int) -> Int{
    return Num1 + Num2
}
  • 省略一些参数的参数 label
// MARK:函数- 省略一些参数的参数 label
func addNumber(_ num1:Int, _ num2:Int) -> Int{
    return num1 + num2
}
  • 接受函数作为参数的函数
// MARK:函数- 接受函数作为参数的函数
/// 接受函数作为参数的函数
/// - Parameters:
///   - addNumbe: 自定义的一个函数,需要有存在的函数
///   - num1: 输入的参数1
///   - num2: 输入的参数2
func funcContains(addNumbe:(Int,Int) -> Int, num1:Int, num2:Int) -> Int {
    return addNumbe(num1,num2)
}

12. 函数:闭包

// MARK:函数- 闭包
func testClosure(){
    let adder:(Int,Int) -> Int = {(x,y) in x + y}
    print("adder: \(adder(10,10))")
    
    // 带有速记参数名的闭包---{$0 * $0} $0-表示闭包中的第一个参数  $1-表示闭包中的第二个参数
    let shorthand :(Int) -> Int = {$0 * $0}
    print("shorthand: \(shorthand(10))")
    
    // 将一个闭包传递给函数
    let addWithClosure = funcContains(addNumbe: adder, num1: 10, num2: 13)
    print("addWithClosure:\(addWithClosure)")
}

13. 枚举

  • 正常枚举
// MARK:枚举 - 正常枚举
enum testEnum {
    case One,Two,Three,Four,Five
}
    
func testEnumeration(){
    // 正常枚举
    let oneEnum = testEnum.One
    print("oneEnum:\(oneEnum)")
}
  • 迭代枚举
// MARK:枚举 - 迭代枚举
enum testEnumLanguage : CaseIterable {
    case Hi,Hello,Hallo,Bonjour,여보세요,привет
}

func testEnumeration(){
    // 迭代枚举
    for language in testEnumLanguage.allCases {
        print("language:\(language)")
    }
}
  • 带有 String 原始值的枚举
// MARK:枚举 - 带有 String 原始值的枚举
enum testEnumStr:String {
    case One = "你好"
    case Two = "Hello"
    case Three = "Hallo"
    case Four = "Bonjour"
    case Five = "こんにちは"
    case Six = "여보세요"
}

func testEnumeration(){
    // 带有 String 原始值的枚举
    let sayEnumStr = testEnumStr.One
    print("sayEnumStr:\(sayEnumStr)")
    // 打印原始值 -- 也可以说是打印枚举对应的值
    let sayEnumStrRawValue = testEnumStr.Five.rawValue
    print("sayEnumStrRawValue:\(sayEnumStrRawValue)")
}
  • 带有关联值的枚举
// MARK:枚举 - 带有关联值的枚举
enum testEnumCountriesLanguage {
    case Hi
    case Hello(String)
    case Hallo(Int)
    case Bonjour(Double)
}

func testEnumeration(){
    // 带有关联值的枚举
    let sayCountries = testEnumCountriesLanguage.Hello("Hello,Are ok?")
    let sayCountriesTwo = testEnumCountriesLanguage.Hallo(20)
    let satCountriesThree = testEnumCountriesLanguage.Bonjour(23.0)
    print("sayCountries:\(sayCountries) sayCountriesTwo:\(sayCountriesTwo) satCountriesThree:\(satCountriesThree)")
}
  • 使用 switch 语句来匹配枚举值
// MARK:枚举 - 使用 switch 语句来匹配枚举值
enum testSwitchEnumCountriesLanguage {
    case Hi
    case Hello(String)
    case Hallo(Int)
    case Bonjour(Double)
}

func testEnumeration(){
    // 使用 switch 语句来匹配枚举值
    let switchEnum = testSwitchEnumCountriesLanguage.Hello("Are OK?")
    switch switchEnum {
    case .Hi:
        print("Hi 你个头")
    case .Hello(let value): // 提取 String 值
        print("你跟我说什么:\(value)")
    case .Hallo(_): // 忽略 Int 值
        print("你说的是什么?")
    default:
        print("没有你还不行了")
    }
}

14. 结构体

// MARK: 结构体 - 正常结构体
struct UserInfo {
    var name : String
    var age  : Int
    var sex  : String
}
    
// MARK: 结构体 - 如果属性有初始值,逐一构造器会将其作为默认参数值
struct UserInfoTwo {
    var name : String = "Z"
}

func testStructure(){
    // 结构体自动创建一个逐一构造器,该构造器接收与所有属性匹配的参数
    let A = UserInfo(name: "Jason", age: 30, sex: "男")
    print("Who? \(A)!")
    
    // 如果属性有初始值,逐一构造器会将其作为默认参数值
    let Z = UserInfoTwo()
    print("Who? \(Z)")
    
    // 访问属性
    print("\(Z.name),你好啊")
}