• 目前随着公司开发模式的变更,swift也显得越发重要,相对来说...好了,废话不多说了,直接把我对swift语法的一些理解奉献给大家,希望能对学习swift语法的朋友有所帮助,如有不足之处,还请多多包涵,如果有错误之处,欢迎指正

    目前随着公司开发模式的变更,swift也显得越发重要,相对来说,swift语言更加简洁,严谨.但对于我来说,感觉swift细节的处理很繁琐,可能是还没适应的缘故吧.基本每写一句代码,都要对变量的数据类型进行判断,还要进行强转等等.

    好了,废话不多说了,直接把我对swift的语法的一些理解奉献给大家,希望能对学习swift语法的朋友有所帮助,如有不足之处,还请多多包涵,如果有错误之处,欢迎指正

    Swift 介绍

    简介
    Swift 语言由苹果公司在 2014 年推出,用来撰写 OS X 和 iOS 应用程序
    2014 年,在 Apple WWDC 发布

    历史
    2010 年 7 月,苹果开发者工具部门总监 Chris Lattner 开始着手 Swift 编程语言的设计工作
    用一年时间,完成基本架构
    Swift 大约历经 4 年的开发期,2014 年 6 月发表
     
    克里斯·拉特纳何许人?
              LLVM 项目的主要发起人与作者之一
              Clang 编译器的作者
              苹果公司『开发者工具』部门的主管
              领导Xcode、Instruments等编译器团队
              Swift的大部分基础架构均由他1人完成
     
    特点
         从它的语法中能看到`Objective-C、JavaScript、C#、Python`等语言的影子
         语法简单、代码简洁、使用方便
         可与Objective-C混合使用(相互调用)
         提供了类似 Java 的名字空间(namespace)、泛型(generic)、运算对象重载(operator overloading)
     
    为什么设计Swift语言
         让应用开发更简单、更快、更稳定
         确保最终应用有着更好的质量
     
    Swift初体验
    Playground是什么?
    从Xcode6开始出现(Swift开始出现)
    翻译为:操场/游乐场
    对于学习Swift基本语法非常方便
         所见即所得(快速查看结果)
         语法特性发生改变时,可以快速查看.
     
    一.Swift最基本的语法变化
     
    1.导入框架  
    1 OC: #import <UIKit/UIKit.h>
    2 Swift: import UIKit 
    2.定义标识符
         OC: int a = 20;
         Swift: let a : Int = 20   ==  let a = 20     
     
         定义标识符格式: let / var 标识符 : 数据类型 = 赋值    
         注意:let声明的是常量,不可以对常量重新赋值
     
         Swift中定义标识符,必须声明该标识符是变量(var)还是常量(let)
         注意:在swift中如果一行代码中只有一条语句,那么语句后面的 ;(分号) 可以省略
                 一行内有多条语句 ; 不可以省略,   不建议一行写多条语句
     
    3.Swift中的打印    
    1 OC: NSLog(@"Hello world”);  /  NSLog(@"%d", a);
    2 //Swift中字符串不需要@
    3 print(a)   /   print("hello world")
     
    二.常量&变量
     
    1.什么是常量和变量?
     
         在Swift中规定:在定义一个标识符时,必须明确说明该标识符是常量还是变量
         使用let来定义常量,定义之后,不能进行修改
         使用var来定义变量,定义之后,可以进行修改
     
    2.常量个变量的使用注意
     
         在使用中,建议先使用常量,这样更安全,防止不小心修改之前的值
         如果需要修改时,再把常量修改为变量
         注意:常量的本质是,指向的内存地址不能修改,但可以找到内存地址对应的对象,修改对象内部的属性
    1 let view : UIView = UIView()
    2 view.alpha = 0.5
    3 view.backgroundColor = UIColor.orangeColor()
     
    三.类型推导
     
    1.什么是类型推导?
         在Swift中,如果在定义标识符的同时直接对其进行赋值,那么系统会自动根据赋的值的数据类型,推导出标识符的类型
         如果定义标识符的同时直接赋值,那么标识符后面的数据类型可以省略
         可以通过option + 鼠标左键来查看标识符的类型
    1 let n = 3.14
    2 let View = UIView()
     
    四.Swift中的基本运算
     
    1.swift中在进行基本运算时,必须保证两个参与运算的值得数据类型一致,否则会报错
         因为swift中没有隐式转换
    1 let m = 20
    2 let n = 3.44
    3 // let result = m + n 错误写法 
    2.数据类型的转化
         将Int 转换为 Double  Double(m)
         将Double 转换为 Int Int(n)
    1 let a : Double = 2.44
    2 let b : CGFloat = 4.55
    3 let result1 = a + Double(b)
     
    五.逻辑分支
     
    1.什么是逻辑分支?
         分支就是if / witch / 三目运算符 等判断语句
         通过分支语句可以控制程序的执行流程
     
    2.if分支语句
     OC中if的写法 : BOOL --> YES/NO
    复制代码
    1  int a = 20
    2  if (a > 0) {
    3     NSLog(@"a大于0")
    4  }
    5  
    6  if (a) {
    7     NSLog(@"a不等于0")
    8  }
    复制代码
     Swift和OC的差异
        1. if后面的()可以省略掉
        2. swift中没有非0(nil)即真  Bool --> true/false
    复制代码
    1 let a = 20
    2 if a > 0 {
    3     print("a大于0")
    4 } else {
    5     print("a不大于0")
    6 }
    7  
    复制代码
    3.三目运算符
         swift中的三目运算符合OC没什么差别
    let result = m > n ? m : n
    4.guard的使用
     
         4.1 guard是Swift2.0新增的语法
     
         4.2 它与if语句非常类似,它设计的目的是提高程序的可读性
     
         4.3 guard语句必须带有else语句,它的语法如下:
     
              4.3.1当条件表达式为true时候跳过else语句中的内容,执行语句组内容
     
              4.3.2条件表达式为false时候执行else语句中的内容,跳转语句一般是return、break、continue和throw
    复制代码
     1 func online(age : Int , IDCard : Bool , money : Int)  {
     2     guard age >= 18 else {
     3         print("回家叫家长")
     4         return
     5     }
     6     guard IDCard == true else {
     7         print("回家拿身份证")
     8         return
     9     }
    10     guard money >= 5 else {
    11         print("回家拿钱")
    12         return
    13     }
    14     print("留下来上网")
    15 }
    16 online(19, IDCard: true, money: 4
    复制代码
     
    5.switch分支
     
         5.1苹果在swift中对swift中对switch进行了很大的加强
     
         5.2 Swift中switch和OC中switch的差异
              switch中后面的()可以省略
              case结束之后可以不加break,也不会产生case穿透
             补充:如果希望产生case穿透,需要在语句结束之后加上fallthrough
                     在swift中switch的case后面可以跟上多个条件, 并且多个条件以 , 分割 
    复制代码
    1 switch sex {
    2 case 0, 1:
    3     print("正常")
    4 default:
    5     print("非正常人")
    6 }
    复制代码

          5.3 swift支持多种数据类型判断 

    复制代码
     1 //浮点型switch判断
     2 switch m {
     3 case 3.14:
     4     print("m是π")
     5 default:
     6     print("m非π")
     7 }
     8  
     9 //字符串switch判断
    10 switch opration {
    11     case "+":
    12         result = a + b
    13     case "-":
    14         result = a - b
    15     case "*":
    16         result = a * b
    17     case "/":
    18         result = a / b
    19 default:
    20     print("非法操作")
    21 }
    22  
    复制代码
    判断区间类型
    什么是区间?
         通常我们指的是数字区间:0~10,100~200
    swift中的区间常见有两种
         半开半闭区间:0..<10 表示:0~9,不包括10
         闭区间:0...10 表示:0~10
    复制代码
     1 let score = 92
     2 
     3 switch score {
     4 case 0..<60:
     5     print("不及格")
     6 case 60..<80:
     7     print("及格")
     8 case 80..<90:
     9     print("良好")
    10 case 90...100:
    11     print("优秀")
    12 default:
    13     print("不合理分数")
    14 }
    15  
    复制代码


    六.循环
     
    常见的循环有:for/while/do while
    1.for循环
         1.1 OC中的for循环写法
    1   for (int i = 0; i < 10; i++) {
    2  
    3   }     
         1.2 swift中的写法 
    复制代码
     1 // 区间遍历 0..<10 0...9
     2 for i in 0..<10 {
     3     print(i)
     4 }
     5 
     6 for i in 0...9 {
     7     print(i)
     8 }
     9  
    10 // 如果一个标识符不需要使用, 那么可以通过 _ 来代替
    11 for _ in 0..<10 {
    12     print("hello world")
    13 }
    复制代码
    2.while循环
         2.1 OC中的写法
     int a = 20
     while (a) {
     }
         2.2 swift中的写法
              2.2.1while后面的()可以省略
              2.2.2没有非0(nil)即真
    1 var i = 10
    2 while i > 0 {
    3     print(i)
    4     i -= 1
    5 }
     
    3.do while循环
    复制代码
    1 // 区别: 不再使用do while --> repeat while
    2 var m = 0
    3 repeat {
    4     print(m)
    5     m += 1
    6 } while m < 10
    复制代码
     
    七.字符串
    1.字符串的介绍 
         1.1字符串在任何的开发中使用都是非常频繁的
     
         1.2OC和Swift中字符串的区别
              在OC中字符串类型时NSString,在Swift中字符串类型是String
              OC中字符串@"",Swift中字符串""
     
         1.3使用 String 的原因
              String 是一个结构体,性能更高
              NSString 是一个 OC 对象,性能略差
              String 支持直接遍历
              String 提供了 String 和 NSString之间的无缝转换
     
    2.字符串的定义
         2.1定义不可变字符串
    let str = "hello swift"
         2.2定义可变字符串
    var strM = "hello world"
    strM = "hello china" 
     
    3.获取字符串的长度
         先获取字符集合,再获取集合的count属性
    let length = str.characters.count
     
    4.遍历字符串
    for c in str.characters {
        print(c)
    }
     
     
    5.字符串的拼接
         5.1字符串之间的拼接
    let str1 = "Hello"
    let str2 = "World"
    let str3 = str1 + str2
         
         5.2字符串和其它标识符间的拼接
    let name = "lgp"
    let age = 18
    let height = 1.98
    let infoStr = "my name is \(name), age is \(age), height is \(height)"
     
         5.3字符串格式化
              比如时间:03:04  如果显示 3 : 4 就不好.所以需要格式化
    let min = 3
    let second = 4
    let timeStr = String(format: "%02d:%02d", arguments: [min, second]) 
     
    6.字符串的截取
     
         6.1简单的方式是将String转成NSString来使用
              在标识符后加:as NSString即可
    复制代码
    1 // 1.方式一: 将String类型转成NSString类型, 再进行截取
    2 // (urlString as NSString) --> NSString
    3 let header = (urlString as NSString).substringToIndex(3)
    4 let footer = (urlString as NSString).substringFromIndex(10)
    5 let range = NSMakeRange(4, 5)
    6 let middle = (urlString as NSString).substringWithRange(range)
    复制代码
         6.1Swift中提供了特殊的截取方式
              该方式非常麻烦
              Index创建较为麻烦
    复制代码
    1 // 2.方式二: Swift原生方式进行截取
    2 let headerIndex = urlString.startIndex.advancedBy(3)
    3 let header1 = urlString.substringToIndex(headerIndex)
    4 
    5 let footerIndex = urlString.endIndex.advancedBy(-3)
    6 let footer1 = urlString.substringFromIndex(footerIndex)
    7  
    8 let range1 = headerIndex.advancedBy(1)..<footerIndex.advancedBy(-1)
    9 let middle1 = urlString.substringWithRange(range1)
    复制代码
     
    八.数组的使用
     
    1.数组的介绍
         1.1 数组(Array)是一串有序的由相同类型元素构成的集合
         1.2 数组中的集合元素是有序的,可以重复出现
         1.3 Swift中的数组
              swift数组类型是Array,是一个泛型集合
     
    2.数组的初始化
         2.1 定义不可变数组,使用let修饰  
              注意:不可变数组要在定义的同时初始化,否则没有意义
         let array = ["why", "yz"]    
     
         2.2 定义可变数组,使用var修饰
              注意:数组是泛型集合,必须确定该数组中存放元素的类型
      //基本写法   
      var arrayM = Array<String>()
      //单写法
      var arrayM = [String]()
     
    3.对可变数组的基本操作(增删改查)
         3.1 添加元素
    arrayM.append("ljp")    
         3.2 删除元素 
    let removeItem = arrayM.removeAtIndex(1)  返回值为删除的元素
    arrayM.removeAll()
         3.3 修改元素
    arrayM[0] = "why"
         3.4 查找元素(根据下标获取元素)
    let item = arrayM[0]
     
    4.数组的遍历
         4.1 遍历下标值
    1 for i in 0..<array.count {
    2     print(array[i])
    3 }
         4.2遍历元素
    for name in array {
        print(name)
    } 
          4.3遍历下标值和元素
    1 for (index, name) in array.enumerate() {
    2     print(index)
    3     print(name)
    4 }

     

    5.数组的合并
         相同类型的数组可以相加进行合并
         可变数组和不可变的数组也能合并
    1 let array1 = ["why", "yz"]
    2 let array2 = ["lmj", "lnj"]
    3 let resultArray = array1 + array2
     
    九.字典的使用
     
    1.字典的介绍
         1.1字典允许按照某个键来访问元素
         1.2字典是由两部分集合构成的,一个是键(key)集合,一个是值(value)集合
         1.3键集合是不能有重复元素的,而值集合是可以重复的,键和值是成对出现的
         1.4Swift中的字典
              Swift字典类型是Dictionary,也是一个泛型集合
     
    2.字典的初始化
         2.1 定义不可变字典,使用let修饰  
              注意:不可变字典要在定义的同时初始化,否则没有意义
                系统会根据[]中存放的是键值对,还是一个个元素,来判断该[]是一个数组还是字典   
    let dict = ["name" : "why", "age" : 18, "height" : 1.88]
        
         2.2 定义可变字典,使用var修饰
              注意:字典是泛型集合,必须制定该数组中存放元素的类型
         基本写法      
    var dictM = Dictionary<String, NSObject>()
         简单写法   
    var dictM = [String : NSObject]() // 常见
     
    3.对可变字典的基本操作(增删改查)
         3.1 添加元素
    dictM.updateValue("why", forKey: "name")    
         3.2 删除元素 
    1 dictM.removeValueForKey("age") 
         3.3 修改元素
    1 //如果原有没有对应的key/value, 那么就添加键值对
    2 // 如果原有已经有对应的key/value, 那么直接修改
    3 dictM.updateValue("1.77", forKey: "height")
    4 dictM["name"] = "why"
         3.4 查找元素(获取元素)
    1 let item = dictM["name"]
     
    4.字典的遍历
         4.1 遍历字典中所有的key
    1 for key in dict.keys {
    2     print(key)
    3 }       
      4.2 遍历字典中所有的value
    1 for value in dict.values {
    2     print(value)
    3 }
          4.3 遍历字典中所有的key / value
    1 for (key, value) in dict {
    2     print(key)
    3     print(value)
    4 }
     
    5.字典的合并
         相同类型的字典也不可以相加进行合并
         可以把其中一个字典改为可变的,遍历不可变得字典,把元素一个一个的添加到另一个不可变字典中
    复制代码
    1 let dict1 = ["name" : "why", "age" : 18]
    2 var dict2 = ["height" : 1.88, "phoneNum" : "+86 110"]
    3 
    4 for (key, value) in dict1 {
    5     dict2[key] = value
    6 }
    7  
    复制代码
     
    十.元组的使用
    1.元组的介绍
         1.1元组是Swift中特有的,OC中并没有相关类型
         1.2它是什么呢?
              1.2.1 它是一种数据结构,在数学中应用广泛
              1.2.2 类似于数组或者字典
              1.2.3 可以用于定义一组数据
              1.2.4 组成元组类型的数据可以称为“元素”
     
    2.为什么使用元组?
         如果字典或数组保存多种数据类型,那么从字典会数组取出来的数据类型是NSObject,我们使用的时候很不方便,要先转换为真实类型
         元组保存多种数据类型,取出来就是该数据的真实类型,不需要转换就能直接使用
     
    3.元组的定义
    1 let infoTuple = ("why", 18, 1.88, "+86 110")
    2 // 使用元组描述一个人的信息
    3 ("1001", "张三", 30, 90)
    4 // 给元素加上元素名称,之后可以通过元素名称访问元素
    5 (id:"1001", name:"张三", english_score:30, chinese_score:90)

     

     

    前言:swift语法基础篇(二)来了,想学习swift的朋友可以拿去参考哦,有兴趣可以相互探讨,共同学习哦. 
     
     
    一.可选类型(重点内容)
     
    1.什么是可选类型?
     
         1.1在OC开发中,如果一个变量暂停不使用,可以赋值为0(基本属性类型)或者赋值为空(对象类型)
         1.2在swift开发中,nil也是一个特殊的类型.因为和真实的类型不匹配是不能赋值的(swift是强类型语言)
         1.3但是开发中赋值nil,在所难免.因此推出了可选类型
          目的:让代码更加严谨
     
    2.可选类型的取值
         可选类型要么是:空值 , 要么是:有值
         只有为可选类型,才能赋值为nil
     
    3.定义可选类型
           3.1 普通写法
      var name : Optional<String> = nil
       
           3.2 简单写法(语法糖) 
    var name : String? = nil
     
    4.给可选类型赋值
         4.1 普通赋值
    name = Optional("why")
         
         4.2 直接赋值
    name = "why" // 系统会对字符串进行包装Optional, 再进行赋值
     
    5.强制解包(取出可选类型中具体的值)
         5.1 为什么要强制解包
              可选类型的值的格式为: Optional("why") 我们要想使用其真实值,必须要解包
     
         5.2 怎么解包?
              在可选类型的标识符后面加!
     print(name!)
              注意:解包前,要先判断可选类型是否为nil , 如果为nil,强制解包会报错
     
    6.可选绑定
    1 if let name = name {
    2     print(name)
    3     print(name)
    4 }
         6.1 系统先判断可选类型是否为nil,如果为nil,就跳过{}中的内容
         6.2 如果有值,会先对name进行强制解包,然后把解包结果赋值给name
     

     

    7.可选类型的应用场景
         可选类型能让代码变得更加严谨
         类型转换后的数据类型一般都为可选类型,因为转换不成功就为nil , 只有可选类型能接收nil
     
         7.1字符串类型转Int类型
     
         
     
         可以看到,类型转换后的类型为可选类型
         使用转换后的结果的时候,一定要先判断是否为nil, 如果为nil, 使用会报错
     
         7.2 根据string创建一个NSURL
    复制代码
    1 let urlString = "www.baidu.com"
    2 
    3 let url : NSURL? = NSURL(string: urlString)
    4 if let url = url {
    5     let request = NSURLRequest(URL: url)
    6
    复制代码
         if let url = url 内部做了以下判断:
         1.判断url是否为nil,为nil 就跳过{}中的内容
         2.不为nil,就对url进行强制解包
         3.将解包后的结果赋值给前面的url
     
         7.3 根据一个plist文件创建一个数组
    1 let path = NSBundle.mainBundle().pathForResource("123.plist", ofType: nil)
    2 
    3 if let path = path {
    4     NSArray(contentsOfFile:path)
    5 }
     
    二.类型转化
    1.is的使用:判断是否是某种类型
    复制代码
     1 //1.is的使用
     2 let infoArray = ["why" , 18 , 1.98]
     3 let item = infoArray[1]
     4  
     5 //item.isKindOfClass(UIButton.self)
     6 
     7 //string是结构体,不能用isKindOfClass
     8 if item is String {
     9     print("是字符串")
    10 }else {
    11     print("不是字符串")
    12 }
    复制代码

     

    2.as的使用
         2.1 as直接使用: swift类型和oc类型的转化
    1 let urlString = "www.baidu.com"
    2 (urlString as NSString).substringToIndex(3)
     
         2.2 as? 的使用: 将NSObject转成某一确定类型的可选类型
     
    复制代码
     1 let item1 = infoArray[0]
     2 let name = item1 as? String
     3 if let name = name {
     4     print(name.characters.count)
     5 }
     6 简写:
     7 if let name = infoArray[0] as? String {
     8     print(name.characters.count)
     9 }
    复制代码
       
        2.3 as! 的使用: 将NSObject转成确定的类型,但如果转化不成功,则程序会崩溃
    1 let count = (infoArray[0] as! String).characters.count
     
    三.函数
     
    1.函数的介绍
     
        1.1 函数相当于OC中的方法
        1.2 函数的格式如下
         func 函数名(参数列表) -> 返回值类型 {
             代码块
             return 返回值
         }
         1.3 func是关键字,多个参数列表之间可以用逗号(,)分隔,也可以没有参数
         1.4 使用箭头“->”指向返回值类型
         1.5 如果函数没有返回值,返回值为Void.并且“-> 返回值类型”部分可以省略
     
    2.常见的函数类型
         
     
    3.内部参数和外部参数
     
         3.1 什么是内部参数
              3.11 在函数内部就可以看到的参数(标识符)就是内部参数
              3.12 默认所有的参数都是内部参数
     
         3.2 什么是外部参数
              3.21 在函数外部就可以看到的参数(标识符)就是外部参数
              3.22 默认从第二个参数开始都是外部参数
              3.23 如果想让第一个参数成为外部参数,可以设置标签:在变量名前加标签即可
              3.24 如果不想要外部参数,可以在参数名称前加_  (_ 和参数名称中间要加一个 空格)
              3.25 也可以给外部参数设置标签  ,相当于给外部参数起别名
     
     
    4.默认参数
         4.1 什么是默认参数?
              如果一个函数需要参数,而我们调用的时候又不想传参,那么在设计函数的时候,可以给函数一个默认的参数
              如果调用函数,不传参数,就按照默认的参数对函数进行处理
     

     

    5.可变参数
         5.1 swift中函数的参数个数可以变化,它可以接收不确定数量的输入类型参数
         5.2 它们必须具有相同的类型
         5.3 我们可以通过在参数类型名后面加入(...)的方式来指示这是可变参数
         作用:方便需求变化时,更改代码,当参数个数需求变更或很多时,可以轻松些代码

     

    6.指针参数
         6.1 默认情况下,函数的参数是值传递.如果想改变外面的变量,则需要传递变量的地址
         6.2 必须是变量,因为需要在内部改变其值
         6.3 Swift提供的inout关键字就可以实现
     

     

     
    7.函数的嵌套
         swift中函数是可以嵌套的,即函数中包含函数,但是不推荐该写法
         OC中方法不可以嵌套
    复制代码
     1 // 函数的嵌套
     2 let value = 55
     3 func test() {
     4     func demo() {
     5         print("demo \(value)")
     6     }
     7     print("test")
     8     demo()
     9 }
    10 demo() // 错误  必须在对应的作用域内调用
    11 test() // 执行函数会先打印'test',再打印'demo'
    复制代码
     
    8.函数的类型
         8.1什么是函数的类型?
              每个函数都有自己的类型, 函数的类型由 函数的参数类型和返回值类型组成
    复制代码
    1 // 定义两个函数
    2 func addTwoInts(a : Int, b : Int) -> Int {
    3     return a + b
    4 }
    5 
    6 func multiplyTwoInt(a : Int, b : Int) -> Int {
    7     return a * b
    8 }
    9  
    复制代码
         这两个函数的类型是 (Int, Int) -> Int
     
         8.2抽取两个函数的类型,并且使用
    复制代码
     1 // 定义函数的类型
     2 var mathFunction : (Int, Int) -> Int = addTwoInts
     3 
     4 // 使用函数的名称
     5 mathFunction(10, 20)
     6 
     7 // 给函数的标识符赋值其他值
     8 mathFunction = multiplyTwoInt
     9 
    10 // 使用函数的名称
    11 mathFunction(10, 20)
    复制代码
     
         8.3 函数作为方法的参数
    复制代码
    1 // 3.将函数的类型作为方法的参数
    2 func printResult(a : Int, b : Int, calculateMethod : (Int, Int) -> Int) {
    3     print(calculateMethod(a, b))
    4 }
    5 
    6 printResult(10, b: 20, calculateMethod: addTwoInts)
    7 printResult(10, b: 20, calculateMethod: multiplyTwoInt)
    复制代码
     
         8.4函数作为方法的返回值
    复制代码
     1 // 1.定义两个函数
     2 func stepForward(num : Int) -> Int {
     3     return num + 1
     4 }
     5 
     6 func stepBackward(num : Int) -> Int {
     7     return num - 1
     8 }
     9 
    10 // 2.定义一个变量,希望该变量经过计算得到0
    11 var num = -4
    12 
    13 // 3.定义获取哪一个函数
    14 func getOprationMethod(num : Int) -> (Int) -> Int {
    15     return num <= 0 ? stepForward : stepBackward
    16 }
    17  
    18 // 4.for循环进行操作
    19 while num != 0 {
    20     let oprationMethod = getOprationMethod(num)
    21     num = oprationMethod(num)
    22     print(num)
    23 }
    复制代码

     
    四.枚举类型
     
    1.什么是枚举?
     
         1.1 枚举是一种数据类型,枚举是一组具有共同特性的数据的集合
         1.2 枚举可以让我们更安全的使用数据
         1.3 oc中只能对枚举成员赋值为整型
         1.4 swift中的枚举更加灵活,可以给每一枚举成员赋值,这些值可以为字符,字符串,整型,浮点型等
     
    2.枚举类型的定义
     
         2.1 使用enum关键词,把枚举定义在一个大括号内
    1      enum <#name#> {
    2           case <#case#>
    3      }
     
         2.2 case关键词表明新的一行成员值将被定义
     
         2.3 不像 C 和 Objective-C 一样,Swift 的枚举成员在被创建时不会被赋予一个默认的整数值 (0.1.2.3...)
     
         2.4 定义方式二: 多个成员值可以写在同一行
    1 enum Planet {
    2   case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
    3 }
         
    3.枚举类型的使用
    复制代码
     1 enum Direction : Int{
     2     case East = 1 , West , North , Sourth
     3 }
     4 //完整写法
     5 let d : Direction = Direction.North
     6 //简单写法:根据上下文能推导出确定的类型
     7 var d1 = Direction.East
     8 d1 = .West
     9 
    10 //枚举类型的使用
    11 let btn = UIButton(type: .Custom)
    复制代码
     
    4.给枚举类型赋值
     
         4.1 枚举类型赋值可以是字符串/字符/整型/浮点型
         4.2 注意: 如果给枚举类型赋值, 则必须在枚举类型后面说明赋值的类型 
         4.3 给枚举类型赋的值的类型,必须跟说明的类型一致,否则会报错
    复制代码
     1 let btn = UIButton(type: .Custom)
     2 
     3 enum Direction : String{
     4     case East = "1"
     5     case West = "3"
     6     case North = "6"
     7     case Sourth = "9"
     8 }
     9 var b : Direction = .West
    10  
    11 let a = Direction(rawValue: “6”) 
    复制代码
      
    注意: 通过rawValue:方式取出来的值的类型  为 对应类型的 可选类型
         因为通过这种方法不一定能取出来值,可能为nil   所以为可选类型  比较严谨
     
         4.4给枚举类型赋值方式二
    1      enum Direction2 : Int{
    2          case East = 1 , West , North , Sourth
    3 //只要给第一个成员赋值,会自动按照递增的方式给后面的成员赋值
    4 //相当于 West = 2, North = 3, Sourth = 4
    5 //注意:这种赋值方法只对整型有效,赋值其它类型无效
     
    五.结构体
     
    1.什么是结构体?
     
         1.1结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合
         1.2结构体(struct)指的是一种数据结构
         1.3结构体是值类型,在方法中传递时是值传递
     
    2.结构的定义格式
     
    struct 结构体名称 {
        // 属性和方法
    }
     
    3.在swift中对结构体进行了很大的增强
     
         3.1 扩充构造函数
     
              3.11 默认情况下,创建Location  只能使用Location (x: Double , y : Double) 方法创建
              3.12 但为了让结构体的使用更加灵活, swift中,可以对其构造方法就行扩充 
              3.13 注意: 结构体中值必须为可变的var ,否则没有意义
     
            
            

     

     
         3.2 为结构体扩充方法
      
     
    六.类
     
    1.类的介绍和定义
     
         1.1 Swift也是一门面向对象开发的语言,面向对象的基础是类,类产生了对象
     
         1.2 在swift中如何定义类?
              class是Swift中的关键字,用于定义类
     
         1.3 定义的类,可以没有父类.那么该类是rootClass
     
         1.4 通常情况下,定义类时.继承自NSObject
     
    复制代码
     1 class 类名 : SuperClass {
     2     // 定义属性和方法
     3 }
     4 class Person {
     5     var name : String = ""
     6     var age : Int = 0
     7 }
     8 let p = Person()
     9 p.name = "lkj"
    10 p.age = 18    
    复制代码
     
    2.类的属性定义
     
         2.1类的属性介绍:Swift中类的属性有多种
         存储属性:存储实例的常量和变量
         计算属性:通过某种方式计算出来的属性
         类属性:与整个类自身相关的属性
     

     

    3.监听属性的改变
     
         3.1 在OC中我们可以重写set方法来监听属性的改变 (kvc监听系统属性的改变)
         3.2 Swift中可以通过属性观察者来监听和响应属性值的变化
         3.3 通常是监听存储属性和类属性的改变.(对于计算属性不需要定义属性观察者,因为可以在计算属性的set方法中直接观察)
         3.4 怎么监听?   
              通过willSet 和didSet两个方法来监听 , 统称为属性监听器
              

     

    4.类的构造函数
     
         4.1 构造函数类似于OC中的初始化方法: init方法
         4.2 创建一个类,系统会默认提供一个构造函数
     
         4.3 自定义构造函数 , 一般用来初始化时给属性赋值
              注意:如果自定义构造函数,会覆盖系统默认提供的构造函数 , 如果想保留,需要重写
    复制代码
     1  class Person {
     2      var name : String
     3      var age : Int
     4      // 自定义构造函数,会覆盖init()函数
     5      init(name : String, age : Int) {
     6      // 如果在一个方法中, 属性名称产生了歧义(重名), self.不可以省略
     7          self.name = name
     8          self.age = age
     9      }
    10 }
    11 // 创建一个Person对象
    12 let p = Person(name: "why", age: 18)
    13  
    14  
    15 class Person: NSObject {
    16     var name : String
    17     var age : Int
    18     // 重写了NSObject(父类)的构造方法  在init前面加上override
    19     override init() {
    20         name = ""
    21         age = 0
    22     }
    23 }
    24 // 创建一个Person对象
    25 let p = Person()
    复制代码
     
    5.字典转模型
         5.1 使用kvc的条件?
              5.11 必须继承自NSObject
              5.12 在构造函数中使用,必须先调用super.init()
     
         5.2 利用kvc字典转模型非常方便
     
         5.3 使用kvc注意点
              5.31 属性需要有默认的值
              5.32 基本数据类型默认值一般设置为0
              5.33 对象或结构体类型定义为可选类型(可选类型没有赋值前为nil)
    复制代码
     1 class Person: NSObject {
     2     // 结构体或者类的类型,必须是可选类型.因为不能保证一定会赋值
     3     var name : String?
     4     // 基本数据类型不能是可选类型,否则KVC无法转化
     5     var age : Int = 0
     6     // 自定义构造函数,会覆盖init()函数
     7     init(dict : [String : NSObject]) {
     8         // 必须先初始化对象
     9         super.init()
    10         // 调用对象的KVC方法字典转模型
    11         setValuesForKeysWithDictionary(dict)
    12     }
    13  //如果字典中某些键值对,在类中找不到对应的属性,就会报错
    14     //不想让它报错,可以重写setValue  forUndefinedKey key:
    15     override func setValue(value: AnyObject?, forUndefinedKey key: String) {
    16     }
    17 }
    18 // 创建一个Person对象
    19 let dict = ["name" : "why", "age" : 18]
    20 let p = Person(dict: dict)
    复制代码
     
    6.析构函数
         6.1 swift会自动释放不需要的实例以释放资源
              6.11 swift 通过ARC 处理实例的内存管理
              6.12 当引用计数为0时,系统会自动调用析构函数(不可以手动调用)
              6.13 通常在析构函数中释放一些资源(如:移除通知等操作)
     
         6.2 析构函数的写法
    1 deinit {
    2     // 执行析构过程
    3 }
     
              6.21 示例练习
    复制代码
     1 class Person {
     2     var name : String
     3     var age : Int
     4  
     5     init(name : String, age : Int) {
     6         self.name = name
     7         self.age = age
     8     }
     9  
    10     deinit {
    11         print("Person-deinit")
    12     }
    13 }
    14 
    15 var p : Person? = Person(name: "why", age: 18)
    16 p = nil
    复制代码

     

    前言:swift语法基础篇(二)来了,想学习swift的朋友可以拿去参考哦,有兴趣可以相互探讨,共同学习哦. 
     

     
    一.自动引用计数
     
    1.自动引用计数工作机制
         1.1 swift和oc一样,采用自动引用计数来管理内存
         1.2 当有强引用指向对象,对象的引用计数 +1 , 强引用消失,自动计数 -1
         1.3 如果对象的引用计数为0 , 那么该对象会被销毁
     
    2.循环引用
         2.1 什么是循环引用?
              两个(或多个)对象互相强引用
     
         2.2 循环引用对项目有什么影响
              循环引用会让对象不会被销毁,一直保存在内存中,可能导致项目运行不畅
         
         2.3 怎么解决强引用问题?
              只需要让其中一个对象对另外一个对象的引用变为弱引用即可
              在swift中用waek 相当于OC中的 __weak ,或者使用 unowned 相当于OC中的 __unsafe_unretained
     
    3.weak 和 unowned的区别
         3.1 相同点:
              都是一个弱引用,不会对对象进行retain
         
         3.2 不同点
              3.21 weak(__weak) :当弱引用指向的对象销毁时,该引用会指向nil   所以用weak指向的数据类型为可选类型
              3.22 unowned(__unsafe_unretained) :当弱引用指向的对象销毁时,依然指向原来的内存地址, 容易产生错误(野指针/访问僵尸对象)
              3.23 unowned不支持可选类型
     
    二.可选链
     
    1.什么是可选链?
         简单的说,就是可选类型的对象组成的链条
     
    2.为什么会产生可选链?
         2.1 假设有三个类, 人,狗,玩具   
         2.2 人里面有狗这个属性,狗里面有玩具这个属性, 玩具里面有价格这个属性
         2.3 把玩具这个对象赋值给狗(让狗拥有玩具), 把狗这个对象赋值给人(让人拥有这只狗)
         2.4 想要通过人来修改玩具的价格,就需要 person.dog.toy.price 来修改
         2.5 person.dog这个值得类型是可选类型 ,因为人的狗属性可能为nil   属性,想要使用person.dog ,必须要强制解包
         2.6 person.dog.toy也是可选类型,像这样由可选类型的对象组成的链条就是可选链
         
    3.可选链注意点
         3.1 利用可选链赋值的时候一定要解包
         3.2 利用可选链取值的时候也不要忘记解包
         3.3 利用可选链调用方法的时候 也要先解包
     
    4.利用可选链赋值, 取值,调用方法
         4.1 给可选链赋值:
    复制代码
    1  person.dog!.toy!.price = 50 太危险  强制解包,如果没值,直接程序崩溃
    2  
    3 if let dog = person.dog {
    4     if let toy = dog.toy {
    5         toy.price = 50
    6     }  这样解包虽然安全,但是太麻烦
    7 }
    复制代码
    苹果在swift中推荐使用这种方式来给可选链赋值
    1 person.dog?.toy?.price = 50 
    2 //当person.dog 为nil的时候,后面的操作就不再执行
     
         4.2 从可选链取值: 从可选链中取出的值得类型一定是可选类型 (有可能取不到)
    let price = person.dog?.toy?.price
     
         4.3 可选链调用方法:系统会自动判断可选类型是否有值
    person.dog?.toy?.flying()
     
    三.协议
     
    1.如何定义协议
     
         1.1 swift中协议的方式和类,结构体,枚举相似
    protocol SomeProtocol {
        // 协议方法
    }
     
         1.2 例如:定义一个运动协议
    1 protocol SportProtocol {
    2     func playBasketball()
    3     func playFootball()
    4 }
     
    2.声明一个类,并且遵守协议
         2.1 声明一个基类(不继承其它类),并遵守协议
    复制代码
     1 class SomeClass:FirstProtocol,AnotherProtocol {
     2     // 类的内容
     3     // 实现协议中的方法
     4 }
     5  
     6      例如:
     7 class Person : SportProtocol {
     8     var name : String = ""
     9    
    10     func playBasketball() {
    11         print("打篮球")
    12     }
    13    
    14     func playFootball() {
    15         print("踢足球")
    16     }
    17 }
    复制代码
     
         2.2 类继承自其他类,并遵守协议
    1 class SomeClass:SomeSuperClass, FirstProtocol,AnotherProtocol {
    2     // 类的内容
    3     // 实现协议中的方法
    4 }
     
    3.OC swift不支持多继承, 但是可以通过协议,间接实现多继承
     
    4.协议的继承关系
         4.1 swift中的及协议和OC(NSObject)中的不同 是:NSObjectProtocol
    1 protocol CrazySportProtocol : NSObjectProtocol {
    2     func jumping()
    3 }
     
         4.2 一个协议,可以遵守另一个协议
    1 protocol SportProtocol : CrazySportProtocol {
    2     func playBasketball()
    3 }
         当一个类遵守了这个协议(SportProtocol) 相当于也遵守了CrazySportProtocol 协议, 所以必须实现这两个协议中的方法
     
    5.协议的可选性
     
         5.1 OC中协议可以定义为可选和必选,默认是必选的
         5.2 默认情况下,swift中的协议都是必须实现的 ,否则编译器会报错
         5.3 在swift中如何让协议成为可选的(不用必须实现)
              要在协议前加 @objc ,可以保留OC某些特性,在方法前加optional  该方法就是可选的了
              在实现协议方法时,在方法前面也要加@objc
     
    复制代码
     1 @objc protocol SportProtocol {
     2     func playBasketball()
     3     func playFootball()
     4   //加optional该方法就成为可选的了
     5     optional func jumping()
     6 }
     7  
     8 class Person: SportProtocol {
     9     @objc func playBasketball() {  在方法前也要加上关键字@objc,不管是可选还是必选
    10     } 
    11     @objc func playFootball() {
    12     } 
    13     @objc func jumping() { 
    14     }
    15 }
    复制代码

     

    6.协议在代理模式中的使用
         6.1 一般来说协议都用weak来修饰(弱引用)
         6.2 weak只能用来修饰类
         6.3 在swift中协议既可以被类遵守,也可以被结构体,枚举遵守
     
         
         6.4 如何让协议只能被类准守
              在协议名称后面加上  :class  即可
     
    四.闭包
     
    1.什么是闭包?
         闭包和OC中的block非常相似,一般都用来函数的回调
     
    2.block的回顾
         block作为属性的格式: `@property (nonatomic, strong) void(^finishedCallback)(NSString *)`;
         block作为参数的定义格式:` (void (^)(NSString * str))finishedCallback`
     
    3.闭包的格式:
         (参数列表) -> (返回值类型)
     
    4.闭包的使用

     

    5.尾随闭包
    复制代码
     1  // 尾随闭包 : 如果函数的最后一个参数是一个闭包.那么可以将函数调用写成尾随闭包
     2  //就是把闭包写到()的后面, 本来是写在()里面的
     3  tools?.loadData() { (result) in
     4      print("在ViewController中获取到数据:\(result)")
     5  }
     6        
     7  // 如果函数有且只有一个参数,并且是一个闭包, 那么()也可以省略
     8  tools?.loadData { (result) in
     9      print("在ViewController中获取到数据:\(result)")
    10  }
    复制代码

     

    6.闭包的循环引用
     
         6.1 一般在定义工具类的时候,会在工具类的方法中用到闭包
         6.2 当工具类对闭包有强引用,一个控制器又调用包含该闭包的方法,在闭包方法中使用控制器的属性,就会发生循环引用
         6.3 控制器调用方法,就会对工具类有一个强引用, 闭包又拿到控制器的属性,闭包对象就对控制器有一个强引用
     
         6.4 在内存中就相当于这种表现
              

     

    7.怎么解决闭包的循环引用
     
         与oc中类型,只需要把闭包对控制器的引用改为弱引用
     
    8.怎么改?
     
         当闭包修改控制器的属性时,拿到控制器的属性时,把self(控制器)改成weakself即可
    weak var weakself : ViewController? = self
          
     
    五.swift项目的目录结构简介
     
    1.swift项目目录中没有.h和.m的文件, 只有一个.swift的文件,相当于
    2.swift目录中.swift文件就相当于oc中的.h和.m文件
    3.在swift中,调用项目中的其他源文件不需要导入头文件  (一个 .swift文件就是一个源文件)
     
     
    六.懒加载
     
    1.懒加载的介绍
         1.1 和OC中不同,swift有专门的关键字实现懒加载
         1.2 懒加载本质:当第一次使用时再加载,而且只会被加载一次
         
    2.swift中用lazy关键字来实现懒加载
         2.1 懒加载格式  
    lazy var 变量: 类型 = { 创建变量代码 }()
         = 后面是一个闭包 苹果推荐用闭包来实现懒加载,可在闭包中对变量属性进行初始化
     
         2.2 懒加载的使用
    1 lazy var names : [String] = {
    2   return ["why", "yz", "lmj"]
    3 }()

              当执行到上面代码的时候,names不会被加载到内存中, 当names第一次使用时,才会被加载

              无论names使用多少次,只会被加载一次,也就是说内存中只有一个names属性地址
     
     
    七.swift中的常见注释
     
    1.单行注释
         和OC中的单行注释一样  使用  // 注释内容
     
    2.多行注释
         和OC中的多行注释格式一样   /*  注释内容  */
         不同的是,swift中多行注释可以嵌套使用
     
    3.文档注释
         与oc中不一样  , swift中 用 /// 注释内容  来实现文档注释
     
    4.分组注释
         和oc不一样 oc:  #pragma mark - 注释内容
         swift:  //MARK : - 注释内容
     
    八.访问权限
     
    1.internal :内部的
         1.1 当不指定具体的访问权限时,默认为internal
         1.2 internal的访问权限: 在当前项目(包)的任何地方都能访问
     
    2.private : 私有的
         private的访问权限: 在当前源文件中能够访问    一个 .swift文件就是一个源文件
     
    3.public :公共的
         3.1 public的访问权限 : 可以跨包访问
         3.2 包的概念: 就是一个项目或一个框架   UIKit也是一个框架
     
    九.异常处理
     
    1.在swift中,如果一个方法的最后有一个throws,那么这个方法能抛出异常
         正则表达式就能抛出异常:
         NSRegularExpression(pattern: <#T##String#>, options: <#T##NSRegularExpressionOptions#>)
     
     
    2.如果一个方法抛出异常,必须要对异常进行处理,否则编译报错
     
    3.异常处理的三种方式
         3.1 try : 手动处理异常,可以拿到异常(error)
              要在方法前面加上try   而且外面要用do 包装
        
          //try方式 --> 手动处理异常, 并且可以获取到最终的异常结果
          do {    //如果有异常error有值      
          let regex = try NSRegularExpression(pattern: "", options: .CaseInsensitive)
          } catch {     //通过error拿到异常结果
               print(error)
          }

     

         3.2 try? : 系统处理异常
     
         try?方式 : 如果有异常,则返回nil,如果没有异常,则返回结果   结果(regex)为可选类型
                 let regex = try? NSRegularExpression(pattern: "", options: .CaseInsensitive)
                 regex?.matchesInString("", options: [], range: NSMakeRange(0, 0))
     
         3.3 try! :告诉系统不可能有异常
     
               try!方式(不推荐)  注意:一旦发生异常,程序就会崩溃
                let regex = try! NSRegularExpression(pattern: "", options: .CaseInsensitive)
     
    十.如何抛出异常
    1.在方法参数的后面加上 throws  ,一定要有返回值
     
    2.在某些具体的情况下抛出异常
         比如:传的参数不对等等  ,内部要对参数进行判断
     
    3.抛出的异常,一般定义为枚举类型  枚举后面要跟上 ErrorType 这种类型
     

     

    十一.OC和swift相互调用
     
    1.swift中调用oc
         1.1 创建一个桥接文件 (.h的文件) 文件名一般为 Bridge.h
         1.2 在桥接文件中导入oc的头文件
         1.3 配置桥接文件     工程 —> BuildSetting —> 搜索bridging   在后面写入Bridge.h 的相对路径
     

     

    2.oc中调用swift
         2.1 项目名称要规范 (不能有中文和特殊字符)
         2.2 swift中的类,属性,方法名 前面要加 public
         2.3 在oc文件中导入  工程名-Swift.h  的头文件  工程名-Swift.h  系统会自动生成
     

     

    展开全文
  • 循环 OC风格的 for // 传统写法 for var i = 0;...Swift风格的 for // 遍历 0 ~ for i in 0..10 { print(i) } print("---") // 遍历 0 ~ 10 for i in 0...10 { print(i) } 阶段性小结 Sw

    循环

    OC风格的 for

    // 传统写法
    for var i = 0; i < 10; i++ {
        print(i)
    }
    

    Swift风格的 for

    // 遍历 0 ~ <10
    for i in 0..<10 {
        print(i)
    }
    
    print("---")
    
    // 遍历 0 ~ 10
    for i in 0...10 {
        print(i)
    }
    
    • 阶段性小结
      • Swift 中使用 in 关键字标示循环的范围
      • 0..<10 表示从0到9
      • 0...10 表示从0到10
      • 注意之间不能出现空格

    特殊写法

    for _ in 0...10 {
        print("hello")
    }
    
    • 阶段性小结
      • 如果不关心循环本身的索引,可以使用 _ 忽略
      • 这一技巧在之前的分支演练中出现过

    操练:
    /*
    for循环
    格式: for (初始化表达式;循环保持条件;循环后表达式) {需要执行的语句}
    OC:
    int sum = 0;
    for (int i = 0; i <= 10; i++) {
        sum = i++;
    }
    NSLog(@"%d", sum);


    int sum = 0;
    int i = 0;
    for (; i <= 10; i++) {
        sum = i++;
    }
    NSLog(@"%d", sum);


    int sum = 0;
    int i = 0;
    for (; i <= 10; ) {
        sum = i++;
        i++;
    }
    NSLog(@"%d", sum);




    int sum = 0;
    int i = 0;
    for ( ; ; ) {
        sum = i++;
    i++;
    if (i > 10) {
        break;
    }
    }
    NSLog(@"%d", sum);


    int sum = 0;
    int i = 0;
    for ( ; ; ) {
        sum = i++;
        i++;
    NSLog(@"%d", sum);
    }
    如果只有一条指令for后面的大括号可以省略
    for后面的三个参数都可以省略, 如果省略循环保持语句, 那么默认为真




    Swift:
    0.for后的圆括号可以省略
    1.只能以bool作为条件语句
    2.如果只有条指令for后面的大括号不可以省略
    3.for后面的三个参数都可以省略, 如果省略循环保持语句, 那么默认为真


    */
    var sum:Int = 0
    for var i = 0 ; i <= 10 ; i++
    {
        sum = i++
    }
    print(sum)


    var sum1:Int = 0
    var i1 = 0
    for  ; i1 <= 10 ; i1++
    {
        sum1 = i1++
    }
    print(sum1)


    var sum2:Int = 0
    var i2 = 0
    for ; i2 <= 10;
    {
        sum2 = i2++
        i2++
    }
    print(sum2)




    var sum3:Int = 0
    var i3 = 0
    for ; ;
    {
        sum3 = i3++
        i3++
        if i3 > 10
        {
            break
        }
    }
    print(sum3)




    /*
    for in循环
    格式: for (接收参数 in 取出的参数) {需要执行的语句}
    for in含义: 从(in)取出什么给什么, 直到取完为止
    OC:
    for (NSNumber *i  in @[@1, @2, @3, @4, @5]) {
        NSLog(@"%@", i);
    }


    NSDictionary *dict = @{@"name":@"lnj", @"age":@30};
    for (NSArray *keys  in dict.allKeys) {
        NSLog(@"%@", keys);
    }


    NSDictionary *dict = @{@"name":@"lnj", @"age":@30};
    for (NSArray *keys  in dict.allValues) {
        NSLog(@"%@", keys);
    }


    Swift:
    for in 一般用于遍历区间或者集合
    */


    var sum4:Int = 0
    for i4 in 1...10 // 会将区间的值依次赋值给i
    {
        sum4 += i4;
    }
    print(sum4)


    for dict in ["name":"lnj", "age":30]
    {
        print(dict);
    }


    for (key, value) in ["name":"lnj", "age":30]
    {
        print("\(key) = \(value)")
    }




    展开全文
  • 浅谈Swift语法

    2015-04-12 10:18:42
    Apple 在2014年6月的WWDC发布了一款新型的

    Apple 在2014年6月的WWDC发布了一款新型的开发语言,许多美国程序员的价值观貌似和我们很大的不同,在发布的时候我们可以听到,场下的欢呼声是接连不断的。如果换作我们,特别是像有Objective-C开发经验的开发者,是否也能和他们一样,乐观积极的面对这一新型的,剔除C的语言呢?当然,这对很多不愿意使用或者反感Objective-C的开发者们,提供了一条途径进行iOS本地应用开发。


    好了,言归正传,这里,我从一个iOS开发人员的角度,来浅谈一下Swift的语法!


    首先,一个很简单的用法,输出函数:

    println("Hello, world")

    从这段代码里,我们可以发现这个函数名好像在Java里见过:

    System.out.println("Hello world");

    根据Apple在其书籍《The Swift Programming Language》中的描述,这句代码实际上已经是可以做为一个独立的程序来运行[1],在调用这个函数时,并不需要写多余的代码,这实际上反应了该语言的简洁性。同时,我还发现,这句代码后没有我们常见的 “ ; " 分号,这是学某个语言的节奏吗?好像是python还是哪个?


    在变量声明这一块,我们使用了var来作为变量声明符,比如说:

    var myVariable = 42
    myVariable = 50

    我们发现,这里的用法和Javascript比较相似,使用var来定义变量,并不声明变量类型。它的格式就是 var 变量名。


    对于常量声明,Swift使用类似F#的let来声明,比如说:

    let myConstant = 42



    除了类似于Javascript的变量声明外,这里也提供了类似于Jscript和C#的语法,为变量指定类型。同时这里也和一些函数式语言如F#有点相像。说点题外话,尽管我早知道Javascript和JScript是不同的,但是实际的不同是我在使用Unity脚本时才发现的,Unity脚本支持Javascript,但实际上,起初很多语法我并没有见过,直到我在MSDN上找到了JScript的文档和教程,才发现这实际上是JScript。Unity文档中很多都是指向MSDN的。

    这里显示了如何指定变量类型:

    let explicitDouble: Double = 70


    如果我们要转换变量的类型,必须显式的转换,如:

    let label = "The width is "
    let width = 94
    let widthLabel = label + String(width)
    

    转换的方式就是:目标类型(变量)。这种转换方式我是不赞同的,如果能像Java一样自动转换那就更好了。


    相信很多学过C以及类C语言的朋友对%d不陌生吧,我常常拿它用来把整形(int)塞进字符串里,这里同样有个长得像的方法:

    let apples = 3
    let oranges = 5
    let appleSummary = "I have \(apples) apples."
    let fruitSummary = "I have \(apples + oranges) pieces of fruit.”

    这个方法就是"字符串\(要转换的变量如int)字符串"。 有点儿类似类C语言里的 XXXX("字符串%d字符串", 要转换的int)。


    现在我们要看一下数组了,数组的基本使用代码如下:

    var shoppingList = ["catfish", "water", "tulips", "blue paint"]
    shoppingList[1] = "bottle of water"
     
    var occupations = [
        "Malcolm": "Captain",
        "Kaylee": "Mechanic",
    ]
    occupations["Jayne"] = "Public Relations”
    第一个和第二个用法大同小异与许多语言,对于Objective-C来说,有趣的是第三个和第四个,我们发现了,无需使用NSArray类,Swift的数组,本身就支持key-value数组。

    同时,我们也能建立字典类型,这个用法是很多语言都存在的:

    let emptyDictionary = Dictionary<String, Float>()
    


    流程控制语句是变更的比较大的,褒义的讲,for-in还有if-else的语法更加自然了:

    let individualScores = [75, 43, 103, 87, 12]
    var teamScore = 0
    for score in individualScores {
        if score > 50 {
            teamScore += 3
        } else {
            teamScore += 1
        }
    }
    teamScore

    实际上,在Objective-C的语法中,只是多了个括号。如果不了解这个语法的可以评论写下或者Google一下。其实猜应该也能猜出来吧。值得一提的是,因为抛弃了C,所以不要想着0为false其余true的用法了,if只能判断boolean。



    这里有一个奇怪的用法,我见识短浅,实在没见过。

    var optionalName: String? = "John Appleseed"
    var greeting = "Hello!"
    if let name = optionalName {
        greeting = "Hello, \(name)"
    }
    各位注意到没,第一个变量optionalName的类型是String,但与此前不同的是,String后面多了个?,这是干嘛的呢。根据文档上说,加了?,就代表这个变量的值是可选的。啥?可选的?什么意思??我想了很久很久,得出了很多错误结论,最后一句话总结,你在其它语言能否int i=NULL?不能吧?懂了吧。我这里说的只是新特性,其它的都不是。



    嗯,终于看到函数了,函数也比较灵(qi)活(pa),比如说实现了多个返回值。


    先从比较简单的函数谈起:

    func greet(name: String, day: String) -> String {
        return "Hello \(name), today is \(day)."
    }
    greet("Bob", "Tuesday")

    这个函数各位应该能猜到是怎么回事吧?这是一个简单的2个参数1个返回值的函数。name和day是参数名,他们:后面就是参数的类型了,这个在JScript中有。返回值类型当然就是->后面的String了。



    灵(qi)活(pa)的部分来了,我以前好多次见过有人问,为啥不能返回多个值啊?我们常用一些类(class)来解决这个问题,但现在容易了,这样就行:

    func getGasPrices() -> (Double, Double, Double) {
        return (3.59, 3.69, 3.79)
    }
    getGasPrices()
    其实看了这个很多人可能和我一样想问,哪里来的变量可以同时接受3个值?事实上,这里的3个dobule返回值是没意义的,演示多返回值而已。


    这里有个例子:

    func count(string: String) -> (vowels: Int, consonants: Int, others: Int) {
        var vowels = 0, consonants = 0, others = 0
        for character in string {
            switch String(character).lowercaseString {
            case "a", "e", "i", "o", "u":
                ++vowels
            case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
            "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
                ++consonants
            default:
                ++others
            }
        }
        return (vowels, consonants, others)
    }

    let total = count("some arbitrary string!")
    println("\(total.vowels) vowels and \(total.consonants) consonants")

    看到没,这里的3个int返回值都有了返回名称,用常量total储存通过.来使用。


    还有就是,函数定义中能嵌套个子函数定义,比如说func a{....func b{.....}}:

    func returnFifteen() -> Int {
        var y = 10
        func add() {
            y += 5
        }
        add()
        return y
    }
    returnFifteen()

    这个应该很好理解。


    很多没有函数编程经验的人看了书,有疑问,说啥是functions are a first-claas type? 其实这个很好理解,就是“函数是一等的”,也可以说是“一等函数”。在很多类C语言中,你如果想把函数做为参数传递出去,要用函数指针或者代理来间接传递吧?但是在Javascript中,函数也是一个类型,这种函数被称为“一等函数”,既然是个类型,就能像普通的变量一样愉快的传来传去。 Swift中的函数就是这样的。


    在Swift中,函数能做为另一个函数的返回值。等等,有点绕口了,这样说吧,一个函数能返回另一个函数,不饶了吧大笑

    func makeIncrementer() -> (Int -> Int) {
        func addOne(number: Int) -> Int {
            return 1 + number
        }
        return addOne
    }
    var increment = makeIncrementer()
    increment(7)


    既然能当返回值传,当然也能当参数传:抓狂

    func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool {
        for item in list {
            if condition(item) {
                return true
            }
        }
        return false
    }
    func lessThanTen(number: Int) -> Bool {
        return number < 10
    }
    var numbers = [20, 19, 7, 12]
    hasAnyMatches(numbers, lessThanTen)



    另外,也支持闭包,如果里面只有一句话,那么就返回那句话的左值

    numbers.map({
        (number: Int) -> Int in
        let result = 3 * number
        return result
        })l



    好了,开始谈谈类了,类其实就是长这样,没有我们期待的Swift Style:

    class Shape {
        var numberOfSides = 0
        func simpleDescription() -> String {
            return "A shape with \(numberOfSides) sides."
        }
    }

    其实结合了前面谈的,其余跟Java差不多,init为构造。

    class Square: NamedShape {
        var sideLength: Double
        
        init(sideLength: Double, name: String) {
            self.sideLength = sideLength
            super.init(name: name)
            numberOfSides = 4
        }
        
        func area() ->  Double {
            return sideLength * sideLength
        }
        
        override func simpleDescription() -> String {
            return "A square with sides of length \(sideLength)."
        }
    }
    let test = Square(sideLength: 5.2, name: "my test square")
    test.area()
    test.simpleDescription()


    好了,有变化的来了,以下代码演示了类属性的getter和setter,这个语法明显有C#的影子,但是(看下面)

    class EquilateralTriangle: NamedShape {
        var sideLength: Double = 0.0
        
        init(sideLength: Double, name: String) {
            self.sideLength = sideLength
            super.init(name: name)
            numberOfSides = 3
        }
        
        var perimeter: Double {
        get {
            return 3.0 * sideLength
        }
        set {
            sideLength = newValue / 3.0
        }
    }

    var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
    triangle.perimeter
    triangle.perimeter = 9.9
    triangle.sideLength

    其实在set里面还有didset,willset。。。。。。。。真实非(sang)常(xin)灵(bing)活(kuang)!


    大部分谈完了,下一章接着讲,嗯,标题加上(1)。总结一下,这个语言我不感觉适合初学者,因为过于灵活,大量的结合了函数编程的语法,我感觉难以控制和统一代码质量。还有本人才疏学浅,这篇文章分析的错误率低于50%就谢天谢地了,请各路神仙,各位老师指教!!!!微笑





    展开全文
  • 是在for循环的时候出现语法错误。代码如下:for var i = 0; i ; i++{ println("hello world") }按理说这是Swift里最简单的for循环的使用了。但是编译器还是报了两个错: ‘++ is not a binary operator’ ...

    最近刚开始学swift,遇到了一个非常诡异的问题。是在写for循环的时候出现语法错误。代码如下:

    for var i = 0; i < 10; i++{
       println("hello world") 
    }

    按理说这是Swift里最简单的for循环的使用了。但是编译器还是报了两个错:

    1. ‘++ is not a binary operator’
    2. Operator is not a known binary operator

    虽然苹果在官方文档里面说,建议通过++i这种方式使用自增运算符,但是依然可以查到相关资料证明,++运算符既是一个前缀运算符(prefix operator),也是一个后缀运算符(postfix operator)。取决于它相对于变量的位置。虽然它作为前缀运算符和后缀运算符的作用不完全相同,但是写在for循环里面按理说是没有任何问题的。

    仔细查了一下苹果介绍“Lexical Structure”的文档,(抱歉不会翻译,姑且称之为词法结构吧)。点击前往文档地址

    其中有一段话介绍了运算符的前缀、后缀特性,摘录如下:

    The whitespace around an operator is used to determine whether an operator is used as a prefix operator, a postfix operator, or a binary operator. This behavior is summarized in the following rules:

    If an operator has whitespace around both sides or around neither side, it is treated as a binary operator. As an example, the + operator in a+b and a + b is treated as a binary operator.

    If an operator has whitespace on the left side only, it is treated as a prefix unary operator. As an example, the ++ operator in a ++b is treated as a prefix unary operator.

    If an operator has whitespace on the right side only, it is treated as a postfix unary operator. As an example, the ++ operator in a++ b is treated as a postfix unary operator.

    第一段话告诉我们,一个运算符到底被swift编译器当做前缀运算符还是后缀运算符处理,是有一套规则的。依据的就是运算符左右的空格。

    下面三段分别解释了如何定义前缀运算符,后缀运算符和二元运算符。

    在文章的最开始的例子中,注意到我们的写法是i++{ 。那么++运算符左右皆无空格,因此被定义为二元运算符(binary operator)。但是在Swift对++运算符的定义中,它只能作为前缀运算符或者后缀运算符使用。于是错误就发生了。

    那为什么会报第二个错误——Operator is not a known binary operator呢?

    因为Swift中可以自定义运算符,在swift编译器尝试使用++运算符失败后,还会试图把++{作为一个自定义的运算符来理解,但是由于我们并没有实现过这个运算符,所以会报出未知运算符的错误。

    解决这个小问题有两种方案,一是改用++i运算。代码如下:

    for var i = 0; i < 10; ++i{
       println("hello world") 
    }

    参考第二条规则,++运算符被正确识别为前缀运算符。由于官方文档推荐在使用自编运算符的时候使用前缀运算符,所以这种方式是被推荐的。

    或者只要在{和++运算符之间添加空格即可。由于我习惯了i++的用法,所以更倾向于使用这种解决方案,代码如下:

    for var i = 0; i < 10; i++ {
       println("hello world") 
    }
    展开全文
  • Swift已经推出了一段时间了,今天来总结一下Swift与Objective-c(以下简称OC)的语法有哪些不同。 1.常量与变量: 在Swift中定义常量和变量很简单,常量使用let关键字,变量使用var关键字。 var numberOfRows = 30...

    Swift已经推出了一段时间了,今天来总结一下Swift与Objective-c(以下简称OC)的语法有哪些不同。

    1.常量与变量:

    在Swift中定义常量和变量很简单,常量使用let关键字,变量使用var关键字。

    var numberOfRows = 30
    let maxNumberOfRows = 100

    在OC中我们声明一个变量的时候需要指定数据类型:

    const int count = 10;
    double price = 23.55;
    NSString *myMessage = @"Objective-C is not dead yet!";

    但是在Swift中我们不用,虽然Swift是强类型语言,但是它可以根据赋值进行类型推断:

    let count = 10
    // count会被识别为Int
    var price = 23.55
    // price会被识别为Double
    var myMessage = "Swift is the future!"
    // myMessage会被识别为String

    当然在Swift中写上变量名也不会有任何问题:

    var myMessage : String = "Swift is the future!"

    2.Swift中不用再写分号了!

    在OC中你需要在每一句的后面写上“;”以表达结束,不然会报错,在Swift中你不需要再写分号了,当然你写上也没有问题。

    var myMessage = "No semicolon is needed"

    3.String

    在Swift中字符串的类型是String,不论你定义的是常量字符串还是变量字符串。

    let dontModifyMe = "You cannot modify this string"
    var modifyMe = "You can modify this string"

    在OC中你需要使用NSString和NSMutableString来区分字符串是否可以被修改。

    在Swift中连接两个字符串组成新字符串非常方便,使用“+”:

    let firstMessage = "Swift is awesome. "
    let secondMessage= "What do you think?"
    var message = firstMessage + secondMessage
    println(message)

    println是Swift中一个全局的打印方法。

    在OC中我们使用stringWithFormat方法:

    NSString *firstMessage = @"Swift is awesome. ";
    NSString *secondMessage = @"What do you think?";
    NSString *message = [NSString stringWithFormat:@"%@%@", firstMessage, secondMessage];
    NSLog(@"%@", message);

    在OC中要判断两个字符串是否相同你不能用“==”,你需要使用方法isEqualToString方法,但是在Swift中你可以使用“==”来判断字符串是否相同。

    var string1 = "Hello"
    var string2 = "Hello"<pre name="code" class="plain">if string1 == string2 {
        println("Both are the same")
    } 

    
    4.Array数组
    

    数组的用法Swift和OC差不多,我们来看示例:

    在OC中:

    NSArray *recipes = @[@"Egg Benedict", @"Mushroom Risotto", @"Full Breakfast", @"Hamburger",
    @"Ham and Egg Sandwich"];

    在Swift中:

    var recipes = ["Egg Benedict", "Mushroom Risotto", "Full Breakfast", "Hamburger", "Ham and Egg
    Sandwich"]

    在OC中你可以向NSArray和NSMutableArray中插入任意类型的参数,但是在OC中只能插入相同的参数。

    和NSArray相似,Swift中的Array也有很多方法,比如count方法返回数组中的元素个数:

    var recipes : [String] = ["Egg Benedict", "Mushroom Risotto", "Full Breakfast", "Hamburger",
    "Ham and Egg Sandwich"]<pre name="code" class="plain">var numberOfItems = recipes.count
    // recipes.count will return 5

    
    在OC中你使用NSMutableArray中的方法addObject来增加数组中的元素,Swift中的方法更简单,你可以使用“+=”,比如:
    

    recipes += ["Thai Shrimp Cake"]
    不过请注意这个方法是数组间的,如果一个单个元素要加入数组中请在元素外面增加[]。

    要取出或者替换数组中的元素,使用索引,这点跟OC中相同:

    var recipeItem = recipes[0]
    recipes[1] = "Cupcake"

    在Swift中可以使用Range来表示范围:比如
    recipes[1...3] = ["Cheese Cake", "Greek Salad", "Braised Beef Cheeks"]
    这里替换的是recipes中的第二到第四个元素。

    5.Dictionary字典

    字典是一种集合类型,由键值对组成,这一点和OC中的NSDictionary很类似,请看示例:

    OC中:

    NSDictionary *companies = @{@"AAPL" : @"Apple Inc", @"GOOG" : @"Google Inc", @"AMZN" :
    @"Amazon.com, Inc", @"FB" : @"Facebook Inc"};

    Swift中:

    var companies = ["AAPL" : "Apple Inc", "GOOG" : "Google Inc", "AMZN" : "Amazon.com, Inc",
    "FB" : "Facebook Inc"]
    你也可以声明它的字典类型:

    var companies: Dictionary<String, String> = ["AAPL" : "Apple Inc", "GOOG" : "Google Inc",
    "AMZN" : "Amazon.com, Inc", "FB" : "Facebook Inc"]

    要遍历一个字典,需要使用元组来保存每一次循环的字典中的信息:

    for (stockCode, name) in companies {
        println("\(stockCode) = \(name)")
    }

    你也可以单独遍历字典中的键或者值:

    for stockCode in companies.keys {
        println("Stock code = \(stockCode)")
    }
    for name in companies.values {
        println("Company name = \(name)")
    }

    如果想给字典添加新的键值对,那么使用如下语句:

    companies["TWTR"] = "Twitter Inc"

    6.Class类

    在OC中创建类的话,会得到两个文件,一个接口文件(.h文件)和一个实现文件(.m文件)。

    而在Swift中生成类只有一个文件.swift文件。

    示例:

    class Recipe {
        var name: String = ""
        var duration: Int = 10
        var ingredients: [String] = ["egg"]
    }

    在上面的示例中我们创建了一个Recipe类,里面有三个属性,并且都声明了类型,做了初始化。在Swift中类在初始化的时候它的属性必须都被初始化。如果你不想设置某个属性的默认值的话,使用?把它加入可选链中:

    class Recipe {
        var name: String?
        var duration: Int = 10
        var ingredients: [String]?
    }
    这样当你创建一个类的实例的时候:

    var recipeItem = Recipe()

    这些可选链中的属性的初始值是nil。你可以给它们赋值:

    recipeItem.name = "Mushroom Risotto"
    recipeItem.duration = 30
    recipeItem.ingredients = ["1 tbsp dried porcini mushrooms", "2 tbsp olive oil", "1 onion,
    chopped", "2 garlic cloves", "350g/12oz arborio rice", "1.2 litres/2 pints hot vegetable
    stock", "salt and pepper", "25g/1oz butter"]

    类可以继承父类和遵守协议,示例:

    OC中:

    @interface SimpleTableViewController : UIViewController <UITableViewDelegate,
    UITableViewDataSource>

    Swift中:

    class SimpleTableViewController : UIViewController, UITableViewDelegate, UITableViewDataSource

    7.Methods方法

    Swift允许你在类、结构体和枚举中创建方法。

    下面是一个没有参数和返回值的方法:

    class TodoManager {
        func printWelcomeMessage() {
            println("Welcome to My ToDo List")
        }
    }

    在OC中调用一个方法的格式如下:

    todoManager printWelcomeMessage];

    在Swift中调用一个方法的格式如下:

    todoManager.printWelcomeMessage()

    如果要建立一个带参数和返回值的方法,格式如下:

    class TodoManager {
        func printWelcomeMessage(name:String) -> Int {
            println("Welcome to \(name)'s ToDo List")
    return 10 }
    }

    "->"用来指示方法的返回值类型。

    你可以这样调用上面的方法:

    var todoManager = TodoManager()
    let numberOfTodoItem = todoManager.printWelcomeMessage("Simon")
    println(numberOfTodoItem)


    8.Control Flow控制流

    Swift中的控制流和循环颇有C语言的风格。

    8.1for循环

    for循环使用 for - in的结构,并且可以和Range(...或者..<)配合使用:

    for i in 0..<5 {
        println("index = \(i)")
    }

    会在控制台输出:

    index = 0

    index = 1

    index = 2

    index = 3

    index = 4 



    如果我们使用...这是个闭集合,结果会返回:

    index = 0

    index = 1

    index = 2

    index = 3

    index = 4

    index = 5 

    如果你想用c中的结构也是可以的:

    for var i = 0; i < 5; i++ {
        println("index = \(i)")
    }

    只不过for后面不用写括号了。


    8.2 if-else结构

    和OC中很像,只不过Swift中更简单一些,条件语句不需要写在括号中:

    var bookPrice = 1000;
    if bookPrice >= 999 {
        println("Hey, the book is expensive")
    } else {
        println("Okay, I can affort it")
    }

    8.3 switch结构

    Switch中的switch结构拥有非常强大的功能。

    示例:

    switch recipeName {
        case "Egg Benedict":
            println("Let's cook!")
        case "Mushroom Risotto":
            println("Hmm... let me think about it")
        case "Hamburger":
            println("Love it!")
        default:
    }
    println("Anything else")

    首先Swift中的switch中可以控制字符串,OC中的NSString是不能被switch控制的,在OC中要实现类似功能你只能使用if-else。

    另外你可以看到在每个case中我们都没有写break,在OC中你必须在每个case中写break,否则在当前case结束后会进入下一个case,在Swift中当前case被执行后就会自动跳出switch,如果需要进入下一个case,添加fallthrough语句。

    最后,switch的case中可以包含Range操作:

    var speed = 50
    switch speed {
    case 0:
        println("stop")
    case 0...40:
        println("slow")
    case 41...70:
        println("normal")
    case 71..<101:
        println("fast")
    default:
        println("not classified yet")
    }

    9.Tuple元组

    元组类型在OC中是没有的,它可以包含多种不同的数据类型,你可以把它用作方法的返回值,这样就可以用一个元组来代替返回一个复杂的对象了。例如:

    let company = ("AAPL", "Apple Inc", 93.5)

    你可以把元组company中的值取出来,用法如下:

    let (stockCode, companyName, stockPrice) = company
    println("stock code = \(stockCode)")
    println("company name = \(companyName)")
    println("stock price = \(stockPrice)")

    或者company.0、company.1这样的方法也能取到值,更好的做法是在定义元组的时候给每个元素起个名字:

    let product = (id: "AP234", name: "iPhone 6", price: 599)
    println("id = \(product.id)")
    println("name = \(product.name)")
    println("price = USD\(product.price)")

    下面是一个把元组作为返回类型的例子:

    class Store {
        func getProduct(number: Int) -> (id: String, name: String, price: Int) {
            var id = "IP435", name = "iMac", price = 1399
            switch number {
                case 1:
                    id = "AP234"
                    name = "iPhone 6"
                    price = 599
            case 2:
                id = "PE645"
                name = "iPad Air"
                price = 499
    default:<span style="font-family: Arial, Helvetica, sans-serif;">break }</span><pre name="code" class="plain">        return (id, name, price)
        }
    }

    
    调用:
    

    let store = Store()
    let product = store.getProduct(2)
    println("id = \(product.id)")
    println("name = \(product.name)")
    println("price = USD\(product.price)")

    10.Optional可选型

    10.1可选型

    可选型通常用在变量之中,可选型的默认值是nil。如果你给一个非可选型的变量赋值nil会报错:

    var message: String = "Swift is awesome!" // OK
    message = nil // compile-time error

    当你的类中的属性没有全部初始化的时候会报错:

    class Messenger {
        var message1: String = "Swift is awesome!" // OK
        var message2: String // compile-time error
    }

    在OC中当你给变量赋值为nil或者没有初始化属性的时候,你是不会收到一个编译时错误的:

    NSString *message = @"Objective-C will never die!";
    message = nil;
    class Messenger {
        NSString *message1 = @"Objective will never die!";
        NSString *message2;<span style="font-family: Arial, Helvetica, sans-serif;">}</span>

    但这不代表你不可以在Swift使用没有初始化的属性,我们可以使用?来表示这是一个可选型的变量:

    class Messenger {
        var message1: String = "Swift is awesome!" // OK
        var message2: String? // OK
    }

    10.2那么我们为什么要用可选型呢?

    Swift语言设计的时候有很多安全方面的考虑,可选型表示了Swift是一门类型安全的语言,从上面的例子中你可以看到Swift中的可选型会在编译时就去检查某些可能发生在运行时的错误。

    考虑下面的OC中的方法:

    - (NSString *)findStockCode:(NSString *)company {
        if ([company isEqualToString:@"Apple"]) {
            return @"AAPL";
        } else if ([company isEqualToString:@"Google"]) {
            return @"GOOG";
        }
    return nil; }

    这个方法用来判断输入的字符串是不是Apple和Google,如果是其他的话返回nil。

    假设我们在类中定义这个方法,并且在类中使用它:

    NSString *stockCode = [self findStockCode:@"Facebook"]; // nil is returned<pre name="code" class="plain">NSString *text = @"Stock Code - ";
    NSString *message = [text stringByAppendingString:stockCode]; // runtime error
    NSLog(@"%@", message);

    
    这段代码是可以通过编译的,但是会在运行时发生错误,原因就是方法中传入FaceBook返回了nil。
    

    上面OC中的代码我们在Swift中的话是这样写的:

    func findStockCode(company: String) -> String? {
       if (company == "Apple") {
          return "AAPL"
       } else if (company == "Google") {
          return "GOOG"
       }
    return nil }<pre name="code" class="plain">var stockCode:String? = findStockCode("Facebook")
    let text = "Stock Code - "
    let message = text + stockCode  // compile-time error
    println(message)

    
    这段代码不能通过编译,可以避免运行时的错误了。显而易见,可选型的应用可以提高代码的质量。
    

    10.3解包可选型

    在上面我们已经看到了可选型的用法,那么我们如何判断一个可选型的变量有值还是为nil呢?

    示例:

    var stockCode:String? = findStockCode("Facebook")
    let text = "Stock Code - "
    if stockCode != nil {
        let message = text + stockCode!
        println(message)
    }

    很像OC中的配对,我们使用if判断语句来做可选型的空值判断。一旦我们知道可选型肯定有值的时候,我们可以使用强制拆封(或者叫解包),也就是在变量名后面加一个感叹号来取得变量的值。

    如果我们忘记做空值判断会怎样?你进形了强制拆封所以不会发生编译时错误

    var stockCode:String? = findStockCode("Facebook")
    let text = "Stock Code - "
    let message = text + stockCode!  // runtime error

    会发生运行时错误,错误提示:

    Can’t unwrap Optional.None 


    10.4可选绑定

    除了强制拆封,可选绑定是一个更简单更好的做法。你使用if - let结构的可选绑定来判断一个变量是不是空值

    示例:

    var stockCode:String? = findStockCode("Facebook")
    let text = "Stock Code - "
    if let tempStockCode = stockCode {
        let message = text + tempStockCode
        println(message)
    }

    if let的意思是如果stockCode有值,那么解包它,并且把它赋给一个临时变量tempStockCode,并且执行下面大括号中(条件块)的代码,否则跳过大括号中的代码。

    因为tempStockCode是一个新的常量,你不必再使用!来获取它的值。

    你可以简化这个过程:

    let text = "Stock Code - "
    if var stockCode = findStockCode("Apple") {
        let message = text + stockCode
        println(message)
    }

    我们把stockCode的定义放到if中,这里stockCode不是可选型,所以在下面的大括号中也不用再使用!如果它是nil,那么大括号中的代码就不会执行。

    10.5可选链

    我们有一个类Code,里面有两个属性code和price,它们的类型是可选型。把上面示例中的stockCode方法的返回值由String改为返回一个Code类型。

    class Stock {
        var code: String?
        var price: Double?
    }
    func findStockCode(company: String) -> Stock? {
        if (company == "Apple") {
            let aapl: Stock = Stock()
            aapl.code = "AAPL"
            aapl.price = 90.32
    return aapl
        } else if (company == "Google") {
            let goog: Stock = Stock()
            goog.code = "GOOG"
            goog.price = 556.36
    return goog }
    return nil }

    现在我们计算买了100个苹果需要多少钱:

    if let stock = findStockCode("Apple") {
        if let sharePrice = stock.price {
            let totalCost = sharePrice * 100
            println(totalCost)
        }
    }

    因为findStockCode的返回值是可选值,我们使用可选绑定来判断,但是Stock的price属性也是可选的,所以我们又用了一个可选绑定来判断空值。

    上面的代码运行没有问题,不用if let我们有更简单的办法,你可以把上面的代码改成可选链的操作,这个特性允许我们把多个可选类型用?连接,做法如下:

    if let sharePrice = findStockCode("Apple")?.price {
        let totalCost = sharePrice * 100
        println(totalCost)
    }





    展开全文
  • swift 基础语法4

    2018-04-13 15:59:48
    一、闭包的基本使用:创建一个swift项目:闭包类似于oc中block,可以通过下面的代码看出:import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() /*闭包...
  • swift 基本语法2

    2018-04-13 15:53:25
    一、循环 for 、 while 、do while(swift中没有do while 是 repeat while)/* 普通的for循环和oc中的一致 */ for var i=0;i&lt;10;i++ { print(i) } /*swift特色循环 0..&lt;10 代表一个区间范围 从0...
  • Swift语法快速入门(一) 近期重新学习了一遍Swift语言,主要以《Swift编程权威指南(第2版)》为教程,学习过程中结合比对Java语言特性将学习心得作为三篇笔记:Swift基础语法Swift面向对象,Swift高级编程。 ...
  • swift笔记1-点语法

    2019-07-10 19:10:00
    for i in 0...3 { firstForLoop += i i } firstForLoop 1 两个点代表是左闭右开 即0,1,2 2 三个点代表全集合 即0,1,2,3 func sumOf(numbers: Int...) -> Int { var sum = 0 ...
  • OC中的for循环写法:for (int i = 0;i &lt; 100;i++) { NSLog(@"i=%zd",i); }Swift中的for循环写法:let a = 100; for i in 0 ..&lt; a { print("a=\(i)"); }Swift中for循环不需要i...
  • swift3 语法摘要

    2017-03-06 17:30:46
    swift3学习基础教程摘要: 1、基础部分 2、基本运算符 3、集合控制流 4、函数:(多返回值函数、函数类型、嵌套函数) 5、枚举 6、类和结构体 7、属性和方法 8、下标 9、构造器 10、引用计数、循环引用 11、可选型 12、...
  • Swift4.0 study1 语法

    2018-01-19 10:29:45
    swift学习第一天 :语法 1.常量和变量 var 修饰变量 (可以修改) let 修饰常量(不可变) print代理oc中的NSLog输出 2.数据类型转换:Swift是强语言(OC是弱语言)故进行转换时必须指明数据类型,即...
  • Swift3语法修改

    2017-03-31 14:47:41
    Swift3中,对语法的使用也进行了修改,下面我们就来看一下在swift3中对哪些语法进行修改。 1.数组排序方法 过去数组排序的两个方法:sortInPlace() 和 sort(),现在分别改名成 sort() 和 sorted() sort()...
  • swift入门语法&&基础教程
  • Swift5.0 基础语法

    2020-03-25 11:45:59
    swift5.0以后ABI已经趋于稳定语法不会有大变化 也是学习的最佳时机 var 定义变量 let 定义常量 常量只能赋值一次 使用之前必须赋值 例如: let view = UIView() view.frame = CGRect(x:0, y:0, width:10, ...
  • oc转swift基本语法

    2016-06-28 15:16:00
    在之前: 学习swift如果英文水平可以的建议观看英文官方文档(The Swift Programming Language),因为这个文档会更新到最新的语法,其他的中文翻译有可能没有及时更新给学习者带来困扰,当然跟我一样的学渣也...
  • import Foundation let useInput = "To write the code for class , you must provide three chunks or sentions of code" var OutputCount = 0 ...这是书上的源代码呀,难道是Swift语法又修改了?
  • : Playground - noun: a place where people can play ...本文章总结swift的一部分基本语法(常量变量,判断语法[if guard switch],循环语句,字符串,字典,元组,可选类型,.... )还有其他语法会后序更新
  • Swift语法

    2016-10-24 21:28:31
    Swift开发入门 简介 Swift 语言由苹果公司在 2014 年推出,用来撰写 OS X 和 iOS 应用程序2014 年,在 Apple WWDC 发布 历史 2010 年 7 月,苹果开发者工具部门总监 Chris Lattner(克里斯·拉特纳) 开始着手 ...
  • 语法类的文档网上比较多,我这里参考:Swift基本语法 事例Demo:链接:http://download.csdn.net/download/riven_wn/9401928 语法须知 2个不需要 不需要编写main函数:全局作用域中的代码会被自动...
1 2 3 4 5 ... 20
收藏数 8,502
精华内容 3,400