喜好

喜好检索

生活 蔬菜

蔬菜大全

思考

见闻与录

BT技术

BT蓝牙技术

标签

Swift学习 2021年04月26日

    简介

    Swift 学习

    Swift类型

    Float
    String
    Int
    
    

    Swift基础初步

    1.代码每行不需要 分号结束;
    
    2.代码没有 python 那样 严格的 空格格式
    
    3.使用 var定义变量 使用 let 定义常量
    
    4.swift代码调用过程类似脚本语言 可以不用main入口函数 顺序执行
    
    5.字符串以u开头标示为 unicode编码let blackHeart = "\u{2665}"   标示 ♥
    
    6.函数定义 
        func PrintNode(_ list: ListNode?) -> Void{}   【Swift】
        public static void main(String[] args) {}     【Java】
    
    7.Java中标示的null 在 Swift 中 标示为 nil
    
    8.值永远不会被隐式转换为其他类型。如果你需要把一个值转换成其他类型,请显式转换
         let label = "The width is"
         let width = 94
         let widthLabel = label + String(width)  //  【Swift必须显示强制转换】
         String A ="123"; int B = 4; System.out.println(A+B); //  【java 隐式转换】
     一种更简单的把值转换成字符串的方法:把值写到括号中,并且在括号之前写一个反斜杠(\)
     \(数值)的写法必须放在字符串内部 而不能放在外部如"I have  apples."+\(apples)【报错】
        let apples = 3
        let oranges = 5
        let appleSummary = "I have \(apples) apples."
        let fruitSummary = "I have \(apples + oranges) pieces of fruit."
    
    9.方括号 [] 来创建数组 Array 和 字典Map 并使用下标和键(key)来访问元素
       Array数组只有下标数值[0....length-1],
       Map只有下标key键 Map[(Key1,Value2),(Key1,Value2)] 不能数值访问
    ═══════════════════════════════════════════════════════════════
    var shoppingList = ["catfish", "water", "tulips", "blue paint"]
    print(shoppingList[1])
    shoppingList[1] = "bottle of water"
    print(shoppingList[1])
    
    var occupations = [
        "Malcolm": "Captain",
        "Kaylee": "Mechanic",
    ]
    print(occupations["Malcolm"])
    occupations["Malcolm"] = "Public Relations"
    print(occupations["Malcolm"])
    ═════════════════════
    water
    bottle of water
    Optional("Captain")
    Optional("Public Relations")
    ═══════════════════════════════════════════════════════════════
    
    10.初始化语法来创建一个空数组或者空字典 
    可以不用定义初始化长度 类似ArrayList区别于String[]
       数组[]------var arr = [类型]()
       字典[Key,Value]------ var dic=[Key类型,Value类型]()
       
    let emptyArray = [String]()  
    let emptyDictionary = [String: Float]()
    
    var shoppingList = []   // 简化新式 arr
    var occupations = [:]   // 简化新式 dic
    
    ═══════════════════════════════════════════════════════════════
    var emptyArray = [String]()  
    
    var aa = "0"
    var bb = "1"
    // emptyArray[0] = aa    // 这里向空数组的 下标0 赋值 会导致错误 
    // emptyArray[1] = bb   // 猜测为当前还没有下标0的值 必须追加才有
    
    emptyArray.append(aa)
    emptyArray.append(bb)
    print(emptyArray[0])
    print(emptyArray[1])
    print(emptyArray)
    ═════════════════════
    0
    1
    ["0", "1"]
    ═══════════════════════════════════════════════════════════════
    var emptyArray = [String]() ;emptyArray[0] = "0";print(emptyArray)
    //当前报错 Fatal error: Index out of range: file  因为空数组没有下标为0的值(未初始化)
    
    11. if 条件控制操作( 没有圆括号包围 判断语句 )
    ═══════════════════════════════════════════════════════════════
    var teamScore = 91
    if teamScore >= 60 && teamScore >= 70  {
    print("当前分数\(teamScore) 及格 评分:良-")
    }else if teamScore >= 70 && teamScore >= 80  {
    print("当前分数\(teamScore) 及格 评分:良")
    }else if teamScore >= 80 && teamScore >= 90  {
    print("当前分数\(teamScore) 及格 评分:良+")
    }else if teamScore >= 90 && teamScore >= 100  {
    print("当前分数\(teamScore) 及格 评分:优")
    } else {
    print("当前分数\(teamScore) 不及格 评分:差")
    }
    ═════════════════════
    当前分数91 及格 评分:良-
    ═══════════════════════════════════════════════════════════════
    
    12. switch  去除掉冗余的break了,必须保留 default:分支 否则报错
    switch 支持任意类型的数据以及各种比较操作——不仅仅是整数以及测试相等
    甚至能在case语句中执行 查询的操作   这个 很舒服的操作啊~~~
    ═══════════════════════════════════════════════════════════════
    let vegetable = "red pepper"
    var selected_index = -1
    switch vegetable {
    case "celery":
        print("Add some raisins and make ants on a log.")
        selected_index = 1
    case "cucumber", "watercress":
        print("That would make a good tea sandwich.")
        selected_index = 2
    case let x where x.hasSuffix("pepper"):   // 在 case 中 判断当前字符串是否以 pepper结尾   并把匹配的字符串复制给了 常量x
        print("Is it a spicy \(x)?")
        selected_index = 3
    default:
        print("Everything tastes good in soup.")
    }
        print("selected_index is \(selected_index)")
    ═════════════════════
    Is it a spicy red pepper?
    selected_index is 3
    ═══════════════════════════════════════════════════════════════
    
    
    
    13. for-in循环操作
    for 【item】 in 【list】 {}
    if 语句中,条件必须是一个布尔表达式——这意味着像 if score { ... } 这样的代码将报错,而不会隐形地与 0 做对比
    ═══════════════════════════════════════════════════════════════
    let individualScores = [11, 22, 33, 44]
    var teamScore = 0
    for score in individualScores {
        teamScore+=score
    }
    print(teamScore)
    ═════════════════════
    110
    ═══════════════════════════════════════════════════════════════
    
    for 【key,value】 in 【Dic】
    for-in 来遍历字典,需要一对儿变量来表示每个键值对
    字典是一个无序的集合,所以他们的键和值以任意顺序迭代结束
    ═══════════════════════════════════════════════════════════════
    let interestingNumbers = [
        "Prime": [2, 3, 5, 7, 11, 13],
        "Fibonacci": [1, 1, 2, 3, 5, 8],
        "Square": [1, 4, 9, 16, 25],
    ]
    var largest = 0
    var kindCount = 0
    for (kind, numbers) in interestingNumbers {   // 双重遍历
        for number in numbers {
            if number > largest {
                largest = number
            }
        }
        kindCount+=1
    }
    print("the dic size is \(kindCount) |||| max value in dic is \(largest)")   // 打印 value==Array<int> 最大的那个
    ═════════════════════
    the dic size is 3 |||| max value in dic is 25
    ═══════════════════════════════════════════════════════════════
    
    14. while 循环操作
    while 来重复运行一段代码直到条件改变。
    ═══════════════════════════════════════════════════════════════
    var sum = 0
    var n = 0
    while n < 4 {
        n += 1
        sum = sum + n
        print("n = \(n)  sum=\(sum)")  // 1开始连续累加
    }
    print("End--> n = \(n)  sum=\(sum)")  // 1开始连续累加
    ═════════════════════
    n = 1  sum=1
    n = 2  sum=3
    n = 3  sum=6
    n = 4  sum=10
    End--> n = 4  sum=10
    ═══════════════════════════════════════════════════════════════
    
    
    15. repeat-while循环操作
    repeat-while 循环条件在结尾,保证能至少循环一次
    ═══════════════════════════════════════════════════════════════
    var m = 1
    var n = 0;
    repeat {
        m *= 2
        n += 1
    } while m < 12345
    
    print("value = \(m)  2的\(n)次方  ")  // 离 12345 最近的 2次方的数值
    ═════════════════════
    value = 16384  2的14次方
    ═══════════════════════════════════════════════════════════════
    
    
    16. 类型?  标示在当前类型追加一种可选机制 当前真实值允许为nil 空 配合 if let 使用来判断当前的 类型? 的值 并把它的类型 赋值给中间变量类型 type 完成 从 type?-->type
     if let 中间常量 = type?
    如果变量的可选值 type? 是 nil,条件会判断为 false,大括号中的代码会被跳过。如果不是 nil,会将值解包并赋 给 let 后面的常量,这样代码块中就可以使用这个值了
    ═══════════════════════════════════════════════════════════════
    var optionalStringA: String? = "Hello"
    print(optionalStringA == nil)
    
    var optionalStringB: String? = nil
    print(optionalStringB == nil)
    
    if  optionalStringA == "Hello" {
    print(String("optionalStringA = \(optionalStringA)" ))
    }
    
    if let itemStrA = optionalStringA {
    print(String("optionalStringA = \(itemStrA)"))
    }
    
    if let itemStrB = optionalStringB {
    print(String("optionalStringB = \(itemStrB)" ))
    }else{
        print("optionalStringB is nil ")
    }
    ═════════════════════
    false
    true
    optionalStringA = Optional("Hello") 
    optionalStringA = Hello
    optionalStringB is nil
    ═══════════════════════════════════════════════════════════════
    
    
    
    17. ??符号  类型? 为 nil时设置默认值时使用??  出现在字符串 \( optionlStr ?? defaultStr)  节省判断的代码量了 
    
    let nickName: String? = nil
    let fullName: String = "John Appleseed"
    let informalGreeting = "Hi \(nickName ?? fullName)"
    print(informalGreeting)   //  打印 Hi John Appleseed
    
    18. swift 语言中 没有 ++ --  这样的自增 自减符号
    var n = 2
    // n++  //  报错
    // n--  // 报错
    n-=1
    print("n = \(n)")  // n = 1
    n+=1
    print("n = \(n)") //  n = 2
    
    
    19.  ..< 和 ... 符号  
    ..<    来表示数值范围 包含下界 不包含上界 
    ... 来表示数值范围 包含下界 也 包含上界 
    
    ═══════════════════════════════════════════════════════════════
    for i in 0..<5 {
       print("i = \(i)")
    }
    
    ═════════════════════
    i = 0
    i = 1
    i = 2
    i = 3
    i = 4
    ═══════════════════════════════════════════════════════════════
    
    
    ═══════════════════════════════════════════════════════════════
    for i in 0...7 {
       print("【i】 = \(i)")
    }
    
    ═════════════════════
    【i】 = 0
    【i】 = 1
    【i】 = 2
    【i】 = 3
    【i】 = 4
    【i】 = 5
    【i】 = 6
    【i】 = 7
    ═══════════════════════════════════════════════════════════════
    
    20. 
    21. 
    
    
     
    

    Swift函数与闭包

    1.使用 func 来声明一个函数,使用名字和参数来调用函数。使用 -> 来指定函数返回值的类型
    函数调用时 必须显示的 标注 输入参数标签, 并且参数位置不可以调换 否则报错
    
    func greet(person: String, day: String) -> String {
        return "Hello \(person), today is \(day)."
    }
    print(greet(person:"张三", day: "周一"))   // Hello 张三, today is 周一.
    // print(greet(person:"张三",  "周一"))   //  报错
    // print(greet("张三", day: "周一"))   //  报错
    // print(greet( day: "周一",person:"张三")) // 报错
    // print(greet("张三", "周一"))   //  报错
    
    2.参数标签(参数别名) 和 默认参数别名_
      默认情况下 定义函数必须给定 参数标签 ,但可以使用参数别名来给同一个参数定义一个新的 参数别名 并且新调用函数必须使用新别名 同时使用 _ 来标示当前参数标签在调用时 不用强制写标签
      【新的参数别名  必须被强制使用 在调用函数处必须改为新的参数别名】
      【使用_ 那么就强制不用输入参数别名 , 强制使用就报错】
      【不使用_  那么就必须强制使用标签名称】
      
      func greet(_ person: String,_ day: String) -> String {
        return "Hello \(person), today is \(day)."
    }
    // print(greet(person:"张三", day: "周一"))   // 报错  强制使用报错
    // print(greet(person:"张三",  "周一"))   //  报错
    // print(greet("张三", day: "周一"))   //  报错
    // print(greet( day: "周一",person:"张三")) // 报错
    print(greet("张三", "周一"))   //  正常运行  Hello 张三, today is 周一.
    
      
    3.多参数标签(参数别名)
    
      func greet(one person: String,two day: String) -> String {
        return "Hello \(person), totwo is \(day)."
    }
    // print(greet(person:"张三", day: "周一"))   // 报错  强制使用报错 必须使用 新的标签名称  为什么这么操作?????   必须使用新的参数别名
    print(greet(one:"李四", two: "周二"))   // 
    
    
    
    
    
    4.使用元组来生成复合值,比如让一个函数返回多个值。 
    太方便,因为在Java中 要返回指定的两个int值,那么就必须创建新的类比如Rect 才能往下走 元祖拿来就用....而且元祖的属性可以自定义
    
    ═══════════════════════════════════════════════════════════════
    func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
        var min = scores[0]
        var max = scores[0]
        var sum = 0
    
        for score in scores {
            if score > max {
                max = score
            } else if score < min {
                min = score
            }
            sum += score
        }
    
        return (min, max, sum)
    }
    let statistics = calculateStatistics(scores:[1, 2, 3, 4, 5])
    print("statistics.min ==\(statistics.min)")    // 元祖的参数表示法
    print("statistics.max ==\(statistics.max)")    // 元祖的参数表示法
    print("statistics.sum ==\(statistics.sum)")    // 元祖的参数表示法
    print("statistics.0 ==\(statistics.0)")  // min: Int   // 元祖的下标序号表示法
    print("statistics.1 ==\(statistics.1)")   // max: Int   // 元祖的下标序号表示法
    print("statistics.2 ==\(statistics.2)") // sum: Int   // 元祖的下标序号表示法
    ═════════════════════
    输入参数: scores:[1, 2, 3, 4, 5]
    statistics.min ==1
    statistics.max ==5
    statistics.sum ==15
    statistics.0 ==1
    statistics.1 ==5
    statistics.2 ==15
    
    
    ═══════════════════════════════════════════════════════════════
    
    5.嵌套函数  外层函数可调用下一级的内层函数形成嵌套函数,但不能跨层级调用
    并且在调用 嵌套函数时 该函数必须出现在该函数定义 之后 否则报错
     ═══════════════════════════════════════════════════════════════
    func returnFifteen() -> Int {
        var y = 10
    
        func add() {
    
                func add_5() {
                    print("add_B_Begin")
                    y += 5
                    print("add_B_End")
                }
    
          print("add_A_Begin")
           add_5()
           print("add_A_End")
        }
    
        add()
        // add_5()   // 这里跨级 调用 将会报错 
        return y
    }
    
    print("result == \(returnFifteen())")
    ═════════════════════
    add_A_Begin
    add_B_Begin
    add_B_End
    add_A_End
    result == 15
    
    ═══════════════════════════════════════════════════════════════
    
    
    6.函数可以作为返回值  函数可以赋值为变量 
    函数是第一等类型,这意味着函数可以作为另一个函数的返回值
    好处 可以把匿名函数这类东西传递出去 实现函数的复用  不用重复定义利于统一管理
    
    ═══════════════════════════════════════════════════════════════
    func makeJieCheng() -> ((Int) -> Int) {
        func jiecheng(number: Int) -> Int {
            var temp = 1;
            for i in 1...number{
                temp *= i
            }
            return  temp
        }
        return jiecheng
    }
    var jiecheng = makeJieCheng()
    
    print("1! = \(jiecheng(1)) ")
    print("2! = \(jiecheng(2)) ")
    print("3! = \(jiecheng(3)) ")
    print("4! = \(jiecheng(4)) ")
    print("5! = \(jiecheng(5)) ")
    ═════════════════════
    1! = 1 
    2! = 2 
    3! = 6 
    4! = 24 
    5! = 120
    ═══════════════════════════════════════════════════════════════
    
    
    
    7.函数作为参数 进行调用
      函数既然能作为返回值返回给 变量, 那么这个变量 也可以作为参数被其他函数调用
      虽然调用这样以函数为参数的时候不怪,但是这样的函数定义起来看起来怪
      
      ═══════════════════════════════════════════════════════════════
      // condition 是一个接受一个 Int 返回 Bool的函数参数
    func has_zige(list: [Int], condition: (Int) -> Bool) -> Bool {
        for item in list {
            if !condition(item) {
                  return false
            }
        }
        return true
    }
    
    // 每门课程 大于 60 算及格,只要出现不及格的课程 就没有资格申请奖学金
    func isJieGe(number: Int) -> Bool {
        return number > 60
    }
    
    var A_scores = [59, 80, 74, 90]
    var B_scores = [66, 77, 88, 90]
    
    has_zige(list: B_scores, condition: isJieGe)
    print("奖学金申请标准: 每门课程 大于 60 算及格,只要出现不及格的课程 就没有资格申请奖学金")
    print("A 分数\(A_scores)")
    print("B 分数\(B_scores)")
    print("A 是否有资格申请奖学金: \(has_zige(list: A_scores, condition: isJieGe))")
    print("B 是否有资格申请奖学金: \(has_zige(list: B_scores, condition: isJieGe))")
    ═════════════════════
    奖学金申请标准: 每门课程 大于 60 算及格,只要出现不及格的课程 就没有资格申请奖学金
    A 分数[59, 80, 74, 90]
    B 分数[66, 77, 88, 90]
    A 是否有资格申请奖学金: false
    B 是否有资格申请奖学金: true
    ═══════════════════════════════════════════════════════════════
      
      
    8.闭包  匿名的函数 { 【partA】in【partB】}   被包括在{} 里 没有名称. 但注意哈  他可以被当做参数与返回值进行传递 那么它的作用就扩大了啊  就不仅仅限于一地之用了
    使用 {} 来创建一个匿名闭包。使用 in 将参数和返回值类型的声明与闭包函数体进行分离
    尼玛  这个 in  很容易忘记啊........
    ═══════════════════════════════════════════════════════════════
    //______________________________________
    // 参数==void  返回值==void 的 闭包
    
    var hello_swift = {         // 参数==void  返回值==void 的 闭包   省略in 关键字
        print("参数==void  返回值==void 的 闭包 --> Hello Swift")
    }
    
    hello_swift()   // Hello Swift
    
     hello_swift = {         // 闭包被覆盖  参数==void  返回值==void 的 闭包 省略in 关键字
        print("参数==void  返回值==void 的 闭包 --> Hello World")
    }
    
    hello_swift()   // Hello World
    
    //______________________________________
    // 参数==Int  返回值==void 的 闭包
    var int_void_close = {         
       ( number : Int ) -> Void in
        print("参数==Int  返回值==void 的 闭包 --> int_void_close(100)  int is \(number)")
    }
    
    int_void_close(100)  //  int_void_close  int is 100
    //______________________________________
     // 参数==Int  返回值==Int 的 闭包
    
    var int_int_close_addself = {        
       ( number : Int ) -> Int  in
       let numer_temp = number
         return numer_temp+1
    }
    //int_int_close_addself(100) == 101
    print("参数==Int  返回值==Int 的 闭包 --> int_int_close_addself(100) == \(int_int_close_addself(100))")
    //______________________________________
    ═════════════════════
    参数==void  返回值==void 的 闭包 --> Hello Swift
    参数==void  返回值==void 的 闭包 --> Hello World
    参数==Int  返回值==void 的 闭包 --> int_void_close(100)  int is 100
    参数==Int  返回值==Int 的 闭包 --> int_int_close_addself(100) == 101
    
    ═══════════════════════════════════════════════════════════════
    
    
    
    
    9.更简洁的闭包表达式 
    有很多种创建更简洁的闭包的方法。如果一个闭包的类型已知,比如作为一个代理的回调,你可以忽略参数,返回值,甚至两个都忽略。单个语句闭包会把它语句的值当做结果返回
    ═══════════════════════════════════════════════════════════════
    var numbers = [1,2,3,4,5]
    // 数组的map 就已经决定了它接受的闭包是一个 Int -> Int 类型的闭包 所以下面省略写法
    let mappedNumbers = numbers.map({ number in 3 * number })
    print("mappedNumbers == \(mappedNumbers)")
    ═════════════════════
    mappedNumbers == [3, 6, 9, 12, 15]
    ═══════════════════════════════════════════════════════════════
    
    
    10.$1 $2 在闭包中的应用
    当一个闭包是传给函数的唯一参数,你可以完全忽略括号。
    $10===第一个参数  可以通过参数位置而不是参数名字来引用参数
    $1===第二个参数  可以通过参数位置而不是参数名字来引用参数
    $2===第三个参数  可以通过参数位置而不是参数名字来引用参数
    ═══════════════════════════════════════════════════════════════
    var numbers = [1,2,4,3,4,6,5]
    // 数组的sorted 就已经决定了它接受的闭包是一个 (Int:Int)->Boolean 类型的闭包 所以下面省略写法
    let sortedNumbers = numbers.sorted { $0 > $1 }
    print("sortedNumbers == \(sortedNumbers)")
    ═════════════════════
    sortedNumbers == [6, 5, 4, 4, 3, 2, 1]
    ═══════════════════════════════════════════════════════════════
    
    
    11.da
    12.da
    13.da
    14.da
    15.da
    16.da
    17.da
    18.da
    

    对象和类