美文网首页
Swift快速入门

Swift快速入门

作者: 金歌漫舞 | 来源:发表于2016-07-18 13:54 被阅读591次

    ****1.常量和变量****

    • let定义常量,一经赋值不允许再修改
    • var 定义变量,赋值之后仍然可以修改
      * 定义常量 let/变量 var
      * 格式:let/var 变量名:类型 = 值
      *提示:Swift提供了自动推导,如果使用默认的数据类型,':'类型 可以省略
      * 格式:let/var 变量名=值,变量类型会根据右侧的结果'自动推导'
      * 定义常量并且直接设置数值
      let x: Int = 10
      * 常量数值一经设置,不能修改,以下代码会报错
      x = 30
      * 使用 : 类型,仅仅只定义类型,而没有设置数值
      let y: Int
      * 常量有一次设置数值的机会,以下代码没有问题,因为 y 还没有被设置数值
      y = 10
      * 一旦设置了数值之后,则不能再次修改,以下代码会报错,因为 y 已经被设置了数值
      y = 50
      print(x + y)
      * 变量设置数值之后,可以继续修改数值
      var z: Int
      z = 100
      z = 200
      print(x + y + z)
      2.自定推导
    • Swift能够根据右边的代码,推导出变量的准确类型
    • 通常在开发时,不需要指定变量的类型
    • 如果要指定变量,可以在变量名后使用':',让后跟上变量的类型
      重要技巧:Option+Click可以查看变量的类型
      没有隐式转换!
      ========
    • Swift对数据类型要求异常严格
    • 任何时候,都不会做隐式转换
      如果要对不同类型的数据进行计算,必须要显示的转换

    注意:Int & Double 都是结构体,而不是基本数据类型

    整数默认的类型是Int
    let x:Int = 200
    小数的默认类型是Double
    let y:Double = 10.5

    不同类型之间不能直接计算
    print(x + Int(y))
    print(Double(x) + y)

    let & var的选择

    • 应该尽量选择常量,只有在必须修改时,才需要修改var
    • 在Xcode 7.0 中,如果没有修改变量,Xcode会提示修改let

    ****Optional可选项****

    • Swift是Swift的一大特色,也是Swift初学者最容易困惑的问题
    • 定义变量时,如果指定是可选的,表示该变量可以有一个指定的类型,也可以是nil
    • 定义变量时,在类型后面添加一个?,表示该变量是可选的
    • 变量可选项的默认值是nil
    • 常量可选性没有默认值,主要用于在构造函数中给常量设置初始值
    // Optional 可能有两个值 (None / Some)
    // 格式(1. 自动推导):var 变量名: Optional = 值
        let x: Optional = 20
    // 格式(2. 指定类型):var 变量
        let y: Optional<Int> = 30
    // 格式(3. 简化格式):var 变量名: 类型? = 值
        let z: Int? = 10
    
     // 可选值在参与计算前,必须`解包 unwarping`
     // 只有`解包(unwrap)`后才能参与计算
     // 在变量后添加一个 `!`,可以强行解包
     // `?` 是用于定义的
    // `!` 是用于解包的,程序员要对每一个 `!` 负责
      print(x! + y! + z!)
    
    • 如果Optional值是nil,不允许参与计算
    • 只有 解包(unwrap)后才能参与计算
    • 在变量后添加一个!,可以强行解包
      注意:必须要确保解包后的值不是nil,否则会报错
      ===========================
     // 常量可选项必须要设置初始值
     let x: Int? //= 20
     x = 20
     // 变量可选项默认值是 nil
     var y: Int? //= 10
     y = 20
    
     // unexpectedly found nil while unwrapping an Optional    value
     // 在对可选项解包时发现 nil,会报错!
      if y == nil {
         print("y值为 nil")
      } else {
        print(x! + y!)
     }
    

    常见错误
    翻译
    在对可选项[解包]是发现nil

    ****??运算符****

    • ??运算符可以用于判断 变量/常量 的数组是nil,如果是则使用后面的值代替

    • 在使用Swift开发时,?? 能够简化代码的编写

      // 常量可选项必须要设置初始值
        var x: Int? //= 20
      // x = 30
      // 变量可选项默认值是 nil
       var y: Int? //= 10
       y = 20
      
       print((x ?? 0) + (y ?? 0))
      

    注意:?? 的优先级低,在使用时,应该注意使用()

    var str: String? = "老王"
    
    // 注意 `??` 的优先级低,在使用时,应该注意使用 `()`
    print((str ?? "无名") + " 你好")
    print(str ?? "无名" + " 你好")
    

    ****控制流****

    if

    • Swift中没有C语言的非零即真的概念

    • 在逻辑判断时必须显示地指明具体的判断条件 true/false

    • if语句条件的()可以省略

    • 但是{}不能省略

      let num = 200
      if num < 10 {
         print("比 10 小")
      } else if num > 100 {
          print("比 100 大")
      } else {
         print("10 ~ 100 之间的数字")
      }
      

    ****三目运算符****

    • Swift中的三目运算保持了和OC一致的风格
      x > 20 ? print("大了") : print("小了")

      /**
          `()` 表示执行
      */
       x > 20 ? print("真的大了") : ()
      

    适当的运用三木,能够让代码写的更加简洁

    ****可选项判断****

    • 由于可选项的内容可能为nil,而一旦为nil则不允许参与计算

    • 因此在实际开发中,经常需要判断可选项的内容是否为nil
      ****单个可选项的判断****
      let url = NSURL(string: "http://www.baidu.com")

      //: 方法1: 强行解包 - 缺陷,如果 url 为空,运行时会崩溃
       let request = NSURLRequest(URL: url!)
      
      //: 方法2: 首先判断 - 代码中仍然需要使用 `!` 强行解包
       if url != nil {
            let request = NSURLRequest(URL: url!)
        }
      
        //: 方法3: 使用 `if let`,这种方式,表明一旦进入 if 分 支,u 就不在是可选项
         if let u = url where u.host == "www.baidu.com" {
            let request = NSURLRequest(URL: u)
          }
      

    ****可选项条件判断****

      //: 1> 初学 swift 一不小心就会让 if 的嵌套层次很深,让代码变得很丑陋
      if let u = url {
      if u.host == "www.baidu.com" {
         let request = NSURLRequest(URL: u)
       }
    }
    
     //: 2> 使用 where 关键字,
     if let u = url where u.host == "www.baidu.com" {
       let request = NSURLRequest(URL: u)
    }
    
    • 小结
    • if let 不能与使用 && || 等条件判断
    • 如果要增加条件,可以使用 where子句
    • 注意:where 子句没有智能提示

    ****多个可选项判断****

        //: 3> 可以使用 `,` 同时判断多个可选项是否为空
         let oName: String? = "张三"
         let oNo: Int? = 100
    
         if let name = oName {
           if let no = oNo {
             print("姓名:" + name + " 学号: " + String(no))
           }
         }
    
      if let name = oName, let no = oNo {
         print("姓名:" + name + " 学号: " + String(no))
     }
    

    判断之后对变量需要修改
    let oName: String? = "张三"
    let oNum: Int? = 18

     if var name = oName, num = oNum {
    
         name = "李四"
          num = 1
    
         print(name, num)
     }
    

    ****guard****

     - guard 是与 if let 相反的语法,Swift 2.0 推出的
    
      let oName: String? = "张三"
      let oNum: Int? = 18
    
       guard let name = oName else {
         print("name 为空")
         return
       }
    
        guard let num = oNum else {
          print("num 为空")
          return
        }
    
        // 代码执行至此,name & num 都是有值的
         print(name)
        print(num)
    
    • 在程序编写时,条件检测之后的代码相对是比较复杂的
    • 使用 guard 的好处
      -能够判断每一个值
      -在真正的代码逻辑部分,省略了一层嵌套

    ****switch****

    • switch 不在局限于整数

    • switch 可以针对任意数据类型进行判断

    • 不再需要break

    • 每一个case后面必须有可以执行的语句

    • 要保证处理所有可能的情况,不然编译器直接报错,不处理的条件放在default分之中

    • 每一个case中定义的变量仅在当前case中有效,而OC中需要使用{}

      let score = "优"

      switch score {
      case "优":
           let name = "学生"
           print(name + "80~100分")
           case "良": print("70~80分")
           case "中": print("60~70分")
          case "差": print("不及格")
         default: break
       }
      
    • switch中同样能够赋值和使用 where子句
      let point = CGPoint(x: 10, y: 10)
      switch point {
      case let p where p.x == 0 && p.y == 0:
      print("中心点")
      case let p where p.x == 0:
      print("Y轴")
      case let p where p.y == 0:
      print("X轴")
      case let p where abs(p.x) == abs(p.y):
      print("对角线")
      default:
      print("其他")
      }

    • 如果只希望进行条件判断,赋值部分可以省略
      switch score {
      case _ where score > 80: print("优")
      case _ where score > 60: print("及格")
      default: print("其他")
      }
      ****循环****

    • OC风格的循环
      var sum = 0
      for var i = 0; i < 10; i++ {
      sum += i
      }
      print(sum)

    • for-in,0..<10 表示从0到9
      sum = 0
      for i in 0..<10 {
      sum += i
      }
      print(sum)

    • 范围0...10表示从0到10
      sum = 0
      for i in 0...10 {
      sum += i
      }
      print(sum)

    注意:..< 和 ... 用于定义 Range 类型,左右都不要添加空格

    格式: for 变量 in 范围 { // 代码 }

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

    ****字符串****

    在 Swift 中绝大多数的情况下,推荐使用 String 类型

    • String 是一个结构体,性能更高
      • String 目前具有了绝大多数 NSString 的功能
      • String 支持直接遍历
    • NSString 是一个 OC 对象,性能略差
    • Swift 提供了 String 和 NSString 之间的无缝转换

    ****字符串演练****

    • 遍历字符串中的字符
      for s in str.characters {
      print(s)
      }

    • 字符串长度
      let str = "hello世界"

      // 返回字符串转换成对应编码的字节数
      // 一个中文在 UTF8 字符集中占 3 个字节
            print(str.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
      
      // 返回字符个数 - 字符串长度
      print(str.characters.count)
      
    • 字符串拼接

    • 直接在""中使用 (变量名) 的方式可以快速拼接字符串

     let name = "老王"
     let age = 18
     let point = CGPoint(x: 100, y: 200)
    
      print("\(name) \(age) \(point)")
    

    我和我的小伙伴再也不要考虑 stringWithFormat 了 :D

    • 可选项的拼接
    • 如果变量是可选项,拼接的结果中会有 Optional
    • 为了应对强行解包存在的风险,苹果提供了 ?? 操作符
    • ?? 操作符用于检测可选项是否为 nil
      • 如果不是 nil,使用当前值
      • 如果是 nil,使用后面的值替代
        let str1 = "Hello"
        let str2 = "World"
        let i: Int? = 32
        str = "(i ?? 0) 个 " + str1 + " " + str2
    • 格式化字符串
      • 在实际开发中,如果需要指定字符串格式,可以使用String(format:...) 的方式

        let h = 8
        let m = 23
        let s = 9
        let timeString = String(format: "%02d:%02d:%02d", arguments: [h, m, s])
         let timeStr = String(format: "%02d:%02d:%02d", h, m, s)
        

    ****String & Range的结合****

    • 在 Swift 中,String 和 Range连用时,语法结构比较复杂

    • 如果不习惯 Swift 的语法,可以将字符串转换成 NSString 再处理

      let helloString = "我们一起飞"
      (helloString as         NSString).substringWithRange(NSMakeRange(2, 3))
      
    • 使用 Range 的写法

      // advancedBy(正数) 向右增加索引值
      // advancedBy(负数) 向左减少索引值
       let startIndex = str.startIndex.advancedBy(1)
       let endIndex = str.endIndex.advancedBy(-1)
      
       let subString3 = str.substringWithRange(startIndex..  <endIndex)
      
      print(subString3)
      
    • 集合
      数组

    • 数组使用 [] 定义,这一点与 OC 相同
      //: [Int]
      let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    • 遍历
      let array1 = ["老王", "老李"]

      // 通过下标遍历数组
      for i in 0..<array1.count {
         print(array1[i])
      }
      
       // 顺序遍历数组
      for s in array1 {
         print(s)
      }
      
      // 遍历同时获取下标
      for s in array1.enumerate() {
        print("\(s.index) \(s.element)")
      }
      
      // 遍历同时获取下标方法2
      for (i, e) in array1.enumerate() {
        print("\(i) \(e)")
       }
      
      // 倒序遍历数组
      for s in array1.reverse() {
        print(s)
      }
      
      // 倒序同时获取下标
       for e in array1.reverse().enumerate() {
        print(e)
      }
      
    • 可变&不可变

    • let 定义不可变数组

    • var 定义可变数组
      let array = ["zhangsan", "lisi"]
      //: 不能向不可变数组中追加内容
      //array.append("wangwu")
      var array1 = ["zhangsan", "lisi"]

           //: 向可变数组中追加内容
           array1.append("wangle")
      
    • 数组的类型

      • 如果初始化时,所有内容类型一致,则数组中保存的是该类型的内容

      • 如果初始化时,所有内容类型不一致,择数组中保存的是 NSObject

        // array1 仅允许追加 String 类型的值
        //array1.append(18)
        
         var array2 = ["zhangsan", 18]
        // 在 Swift 中,数字可以直接添加到集合,不需要再转换成 `NSNumber`
        array2.append(100)
        // 如果向 数组添加 `CG` 结构体,需要使用 `NSValue` 转换
        array2.append(NSValue(CGPoint: CGPoint(x: 10, y: 10)))
        
    • 数组的定义和实例化

      • 使用:可以只定义数组的类型
      • 实例化之前不允许添加值
      • 使用类型 可以实例化一个空的数组
        var array3: [String]
        //: 实例化之前不允许添加值
        //array3.append("laowang")
        //: 实例化一个空的数组
        array3 = String
        array3.append("laowang")
    • 数组的合并

      • 必须是相同类型的数组才能够合并

      • 开发中,通常数组中保存的对象类型都是一样的
        array3 += array1

         // 必须是相同类型的数组才能够合并,以下两句代码都是不允许的
         //array3 += array2
         //array2 += array3
        
    • 数组的删除
      //: 删除指定位置的元素
      array3.removeAtIndex(3)
      //: 清空数组
      array3.removeAll()

    • 内存分配

      • 如果向数组中追加元素,超过了容量,会直接在现有容量基础上 * 2

          var array: [String] = [String]()
        
           for i in 0..<9 {
                 array.append("\(i) - hello")
                  print("\(array) \(array.capacity)")
            }
        

    ****字典****
    -定义
    -同样适用[]定义字典

    • let不可变字典

    • var可变字典
      -[String:NSObject]是最常用的字典类型

      //: [String : NSObject] 是最常用的字典类型
      var dict = ["name": "zhangsan", "age": 18]

    • 赋值

      • 赋值直接dict[key] = value格式
    • 如果key不存在,会设置新值

    • 如果key存在,会覆盖现有值

      //: * 如果 key 不存在,会设置新值
      dict["title"] = "boss"
      //: * 如果 key 存在,会覆盖现有值
      dict["name"] = "lisi"
      dict
      
    • 删除一个KEY
      dict.removeValueForKey("age")

    • 遍历

      • k,v可以随便写

      • 前面的是key

      • 后面的是value

        for d in dict {
           print("\(d.0) \(d.1)")
        }
        
        // 遍历
        for (k, v) in dict {
            print("\(k) ~~~ \(v)")
         }
        
    • 合并字典

      • 如果可以不存在,会建立新值,否则会覆盖现有值
        //: 合并字典
        var dict1 = String: NSObject
        dict1["nickname"] = "大老虎"
        dict1["age"] = 100

          //: 如果 key 不存在,会建立新值,否则会覆盖现有值
           for (k, v) in dict1 {
                 dict[k] = v
            } 
             print(dict)

    相关文章

      网友评论

          本文标题:Swift快速入门

          本文链接:https://www.haomeiwen.com/subject/bfvpjttx.html