Swift语言学习笔记(三)

原创 2017年01月03日 19:47:31


54. Swift中闭包的语法:

{ ( parameters ) -> returnType in

    statements

}

闭包的参数同样可以使常量、变量、inout类型的,但是不能提供默认值。参数列表和元组也可以在闭包中使用。

例如下面的闭包定义用来返回较大值:

{ (a : Int, b : Int) -> Int in return a >= b ? a : b }

当闭包的参数和返回值类型能够被推测出来时(大多数情况下都能被推测出来),可以省略掉参数类型和返回值,例如上面的例子可以简化为:

{ a, b in return a >= b ? a : b }

如果闭包中只有一条语句,则可以省略掉return关键字,例如上面的例子:

{ a, b in a >= b ? a : b }

Swift中还为我们提供了参数的快捷名称:$0$1$2…(数字表示参数的位置,第一个参数为$0),使用快捷名称来定义闭包,可以省略掉in关键字以及前面的参数定义,上面的例子可以继续优化为:

{ $0 >= $1 ? $0 : $1 }

55. 如果闭包作为一个函数的最后一个参数出现,在调用的时候可以将闭包写到函数参数的括号外面去,例如我们用闭包来定义一个冒泡排序:

func sort(nums : Int[], comp : (Int, Int) -> Bool, swap :(inout Int, inout Int) -> ()) -> Int[] {

    var count = countElements(nums) - 1

    for var i = 0; i < count; i++ {

        for var j = 0; j< count - i; j++ {

           if comp(nums[j], nums[j+1]) {

               swap(&nums[j], &nums[j+1])

           }

        }

    }

   

    return nums

}

var arr = [1, 6, 8, 2, 7, 0, 5, 3, 9, 4, 6, 2]

println(sort(arr, >) { (inout a : Int, inout b : Int)-> () in

    if a >= b {

        var temp = a

        a = b

        b = temp

    }

})

如果函数唯一的一个参数是闭包表达式,则调用的时候可以不写省略掉圆括号“()”。

56. 闭包能够记录包含闭包的上下文中定义的变量和常量,并且能够在闭包代码块中修改和访问它们(甚至当这些变量和常量随着作用域的更改不再有效)。例如:

func makeIncrementor(amount : Int) -> ()->Int {

    var total = 0

    var incrementor = {()-> Int in

        total += amount

        return total

    }

   

    return incrementor

}

var inc = makeIncrementor(10)

println(inc())       //输出10

println(inc())       //输出20

println(inc())       //输出30

这里由于创建出来的incrementor函数不会修改amount参数,所以新创建出来的incrementor方法会拷贝一个amount的副本,原来的amount会随着makeIncrementor函数的结束而被释放,但是incrementor函数中确实修改了total变量的值,因此它会保留total变量的一个引用,从而保证total不会随着makeIncrementor函数的结束而被释放掉。

57. Swift中函数和闭包是引用类型。

58. Swift中的枚举类型定义:

enum Direction {

case North

case South

case East

case West

}

也可以在一个case中写多个枚举成员:

enum Direction {

case North, South, East, West

}

59. 对于枚举类型,可以在定义中允许枚举值保存附加信息,例如:

enum Product {

    case Product1(Float,Int)       //Discount, Price

    case Product2(Float,String)    //Discount, Gifts

}

var product1 = Product.Product1(0.8, 120)

var product2 = Product.Product2(0.75, "Product3")

在Switch语句中可以使用变量中保存的信息:

switch product {

case Product.Product1(let discount, let price):

println(“Product1 with a discount of \(discount), and theprice is \(price)”)

case Product.Product2(let discount, let gift):

    println(“Product2 with a discount of\(discount), and with \(gift) as a gift”)

}

60. 枚举类的原生数据(raw value)可以是字符串、字符、整型或者浮点型,在定义的时候在枚举名后面加上冒号和类型来声明,如果原声数据类型是整型,那么对于没有指定的枚举成员会自动递增。例如:

enum ASCIIControlChar : Character {

case Tab = “\t”

case LineFeed = “\n”

case ReturnToLineStart = “\r”

}

注意Swift中字符也是使用双引号来定义的。

enum CompareResult : Int {

case LessThan = 0

caseEqual                   //自动增加为1

caseGreaterThan        //自动增加为2

}

使用toRaw()方法来将枚举值转换为对应的原声数据:

var cmpResult = CompareResult.Equal.toRaw()

使用fromRaw()方法来将原生数据转换为枚举值:

var cmpResult = CompareResult.fromRaw(1)

fromRaw方法返回一个可选类型,当转换失败的时候,返回nil

61. Swift中的结构体中也可以定义方法以及构造函数(或者说初始化函数),但是不能定义析构函数。结构体没有深浅拷贝之说,在赋值的时候都是完全拷贝出一个新的结构体赋给目标变量,类在赋值的时候,如果不使用深拷贝,则只传递引用,结构体无继承。

62. Swift中的结构体在定义好之后,默认会生成一个初始化方法,这个初始化方法需要指定参数名来调用,且参数的顺序要喝结构体中的声明顺序一致:

struct Student {

    var name : String

    var age : Int

    var score : Int

}

var s1 = Student(name : "Someone", age : 15, score: 95)

对于Swift中的类,如果不指定初始化函数的话,不会自动生成类似上面的初始化方法。

63. 对于Swift中的结构体和类,如果在定义的时候所有的属性都给出了初始值,则Swift会自动为其创建一个不含参数的初始化方法,例如:

struct Student {

    var name : String = ""

    var age : Int = 0

    var score : Int = 0

}

var s = Student()

如果一个以上的属性没有初始值,则不会生成不含参的构造方法。

64. Swift中的Dictionary在拷贝或者传参的时候与结构体相同,会深拷贝一份完全相同的Dictionary对象。如果Dictionary的键值中有引用类型,则会拷贝出一个引用来,如果键值都是值类型,则拷贝相同的值。

65. Swift中的Array在拷贝或者传参的时候,不会立即复制一份完全相同的Array对象,而是先临时共享公共的内容,当程序将要修改其中某个Array的元素的时候,另一个Array也同样被修改了(或者说因为两个Array指向同一个共享的内容,所以修改一个也会影响另一个)。只有当Array的大小(元素数量)发生变化的时候,才会完成内容的拷贝,两个Array此时才会各自拥有自己的内容,拷贝的效果和Dictionary对象相同:值类型完全拷贝,引用类型拷贝引用值。例如:

var array1 = [1, 2, 3, 4]

var array2 = array1

array1[3] = 5

println(array2)

这个例子array2输出1,2,3,5,也就是修改array1的第四个元素同时也影响了array2,即由于修改没有改变数组的大小,两个数组共享相同的内容。接着看下面的例子:

var array1 = [1, 2, 3, 4]

var array2 = array1

array1 += 5

array1[3] = 5

println(array2)

输出结果为1,2,3,4,因为在array1中加入元素(“5”)的时候,array1从共享的内容中拷贝出了一份内容,而array2仍然指向原来共享的内容(此时已经不共享了),因此没有受到array1[3]=5这句的影响。

66. 对于Array来说,如果希望数组在复制的时候,不共享共同的内容,除了刻意地修改其大小外,还可以调用unshare()方法(注意:常量数组不能调用unshare()方法),例如:

var array1 = [1, 2, 3]

var array2 = array1

array1.unshare()     //也可以调用array2.unshare()

array1[0] = 5

println(array2)         //输出1, 2, 3

此外,还可以使用copy方法来强制完成拷贝:

var array1 = [1, 2, 3]

var array2 = array1.copy()

array1[0] = 5

println(array2)         //输出1, 2, 3

unsharedcopy比起来要是一个更好的选择,unshare方法只会在需要的时候进行拷贝,而copy方法会在调用的时候立即完成拷贝。

版权声明:本文为博主原创文章,未经博主允许不得转载。

C语言学习入们到精通之学习笔记(一)

为什么我通过博客的形式与大家分享我的学习笔记     对于c语言的学习已经有快3年之久了,对于学习嵌入式的我看来,C是我们的根本也就是我们的核心知识点,想学习好嵌入式就必须精通C语言。在一年之前我对...
  • love131452098
  • love131452098
  • 2016年05月29日 14:39
  • 1383

《从零开始学Swift》学习笔记(Day 40)——析构函数

原创文章,欢迎转载。转载请注明:关东升的博客 与构造过程相反,实例最后释放的时候,需要清除一些资源,这个过程就是析构过程。在析构过程中也会调用一种特殊的方法deinit,称为析构函数。析构函数dein...
  • tonny_guan
  • tonny_guan
  • 2015年11月25日 10:28
  • 1974

Go语言学习笔记10

6 程序测试和文档 6.1 程序测试 1.功能测试 2.基准测试
  • u012855229
  • u012855229
  • 2016年07月14日 07:42
  • 2080

Chrome学习笔记(三):UI组件,皮肤引擎

原创文章,转载请注明:转载自Soul Apogee 本文链接地址:Chrome学习笔记(三):UI组件,皮肤引擎 —— 控件库 这篇文章是接着上篇文章继续聊的,Chrome的代码实在太多,每一...
  • wanfengnianhua
  • wanfengnianhua
  • 2017年04月25日 18:56
  • 252

Dubbo框架学习笔记(三)

Dubbo源码地址:https://github.com/alibaba/dubbo Dubbo开发指南:http://dubbo.io/Developer+Guide-zh.htm Dubbo服务...
  • koalacoco
  • koalacoco
  • 2017年04月03日 20:46
  • 217

≪统计学习精要(The Elements of Statistical Learning)≫课堂笔记(三)

照例文章第一段跑题,先附上个段子(转载的哦~): I hate CS people. They don't know linear algebra but want to teach pro...
  • xiebaochun
  • xiebaochun
  • 2014年06月29日 10:02
  • 3687

Deep Learning(深度学习) 学习笔记(三)

前言:昨天看到微博上分享的深度学习视频,为上海复旦大学吴立德教授深度学习课程,一共六课时,视频地址点击打开链接。在此我结合其他资料,写点个人的学习笔记进行记录。 第三,四课:稀疏编码 本课吴老师...
  • hellonlp
  • hellonlp
  • 2014年01月18日 10:38
  • 5096

R语言学习笔记(一)

加载统计文件R Source File include one statement =>employees source(“R source file path”)帮助函数help(command) ...
  • ghostbear
  • ghostbear
  • 2017年04月03日 20:54
  • 1492

Swift语言和其他计算机语言的比较

Swift集成了传统面向对象编程语言的特性,同时又具备函数式编程的一些特征。如果你曾经学过C#,Python,Ruby或者JavaScript,那么会发现Swift有很多相似之处,很容易上手。 在2...
  • u012260238
  • u012260238
  • 2016年03月03日 10:40
  • 1089

Swift学习笔记(三)

集合类型 Swift中提供了3种基本集合类型(Arrays,Sets,Dictionaries) 与OC一样,集合也分可变不可变,但是并不是用不同的类来初始化.在Swift中,如果将一个集合定义为常量...
  • a276873081
  • a276873081
  • 2016年04月18日 18:40
  • 102
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Swift语言学习笔记(三)
举报原因:
原因补充:

(最多只允许输入30个字)