zoukankan      html  css  js  c++  java
  • Swift的闭包,枚举,类和结构体

    闭包(Closures)


    使用过其它语言的应该对代码块并不陌生,Swift中的闭包与C,OC中的Block相似。
    表示自包括的函数代码块。能够在代码中传递和使用。

    而且能够捕获和存储上下文的变量以及常量值,Swift会为你进行捕获相关的内存操作。


    上一篇文章提到的函数。也是一种特殊的闭包。详细在:
    全局函数是有名字可是不会捕获不论什么值的闭包。
    嵌套函数是有名字且能够捕获域内值的闭包。
    闭包表达式是利用轻量级语法写的能够捕获上下文值的匿名闭包。

    基本的语法

    表达式的一般语法以及简化过程


    上面罗列了同一个行为的五种写法,也标明了简化方法适用的情景。

    跟随闭包


    上面那个闭包若使用跟随闭包的方式来写,则表现为:
    reversed = sort(names) {$0 > $1}

    通常我们会把具有多行的闭包表达式写入跟随闭包。

    比如Array的map方法能够对数组内的每个元素调用一次闭包。返回一个新的数组。


    这里捕获了numbers数组中的每一个值并将output映射到一个新的strings数组中。



    值捕获


    闭包能够在其上下文捕获一些值,即使原域已经不存在。

    上面提到嵌套函数是有名字能够捕获域内值的闭包。

    Swift中最简单的闭包形式即是嵌套函数。



    这里定义了一个嵌套函数makeIncrementor,里面记录了一个变量runningTotal,嵌套在里面的函数能够捕获这个值并将其持有保留住。



    可是假设新声明了一个同样函数的变量/常量引用,则其runningTotal并不共享



    闭包是引用类型,上面声明的常量是指向闭包内容的一个引用,而并不是闭包内容本身。



    枚举


    Swift的枚举十分灵活,case中的值能够是字符串。字符。整型或者浮点型。

    而且能够指定不论什么类型的相关值存储到枚举成员中。

    在Swift里,枚举是一等类型(first-class),它支持类所支持的特性(除了继承)。你能够为它定义一些函数让其富有行为等等。


    基本的语法



    当我们已经确定了其是CompassPoint的时候,能够直接使用.Value省略枚举名的形式赋值。

    switch匹配


    相关值

    前面提到过。我们能够为其指定随意类型的相关值存储到枚举成员中。
    来看以下这个样例


    我们给BarCode枚举存储了一些对应case的相关值,而且能够利用绑定值的方式去訪问它,如在switch中定义了个常量identifier来获取Barcode中QRCode的相关值。


    原始值

    在Swift中,枚举并不会像c,objective-c中的枚举在你未声明枚举值的情况下隐式的赋值0,1。2...仅仅有我们给其赋值时才会推測其值。可是也仅限于Int。
    Swift为其定义了方法来訪问原始值toRaw()或者通过fromRaw(value)訪问其枚举成员。


    因为我们的枚举中并没有5相应的成员,所以其为nil。但假设换为3。则是Green。

    那假设枚举成员是String呢?会不会也会推測值?当然是不太可能了- -
    编译器会报错


    非integer必需要给其赋值才干够。


    类与结构体


    定义,实例声明与属性




    因为这里并没有设置自己定义的指定构造器。所以能够直接使用默认的方式()来初始化一个实例。


    訪问设置属性则使用点语法,只是与Ojbective--C不同的是,Swift同意对结构体的子属性直接赋值。

    另外一个不同则是Swift类不须要.h接口文件。



    在OC中我们想改动Rect.Origin的x值常常须要赋一个新的origin给rect,而Swift中则能够直接改动了。


    在Swift中结构体,枚举和类都能够通过写一些成员函数来为其加入行为。

    构造时则稍有不同,结构体能够为其提供逐一成员构造器。


    这是系统自己主动提供的。而类则没有提供。

    值类型和引用类型


    结构体,枚举和类另外主要不同的一点是类型。

    结构体和枚举为值类型,类则是引用类型。

    值类型指在赋值传递的时候,系统会自己主动为其拷贝一个新值并传递给新声明的变量或常量。


    我们注意在将hd赋值给cinema后马上cinema的width进行了改动,可是再訪问hd.width还是原来的值1920.说明仅仅是将hd的拷贝赋给了cinema而并非hd本身。

    引用类型这是将新的变量或常量指向了原来的对象,而并不是拷贝对象值之后进行赋值。


    这里改动了frameRate,再訪问原来变量的frameRate发现也发生了变化。原因在于他们都指向了同一块堆内存。



    在Swift中。判定引用相等引人了一个恒等符号"==="。来判定是否引用同一实例,不引用同一实例则为"!=="(不等价于)
    那么"==="和"=="的不同在于哪里呢?
    等价于("===")表示两个类类型的常量或变量引用同一个实例。

    而"=="表示两个实例的值是否相等。判定须要遵照类设计者定义的判定标准。


    因为结构体是值类型。我们不使用等价于进行推断。



    类和结构体的异同和选择


    首先来看类和结构体的同样点:
    定义属性用于存储值
    定义方法用于提供功能
    定义附属脚本(subscript)用于訪问值
    定义构造器用于初始化值和配置
    通过扩展以添加默认实现的功能
    符合协议以对某类提供标准功能

    不同点在于:(类)
    继承同意一个类继承还有一个类的特征
    类型转换同意在执行时检查和解释一个类实例的类型
    解构器(析构过程会提到)同意一个类实例释放不论什么其所被分配的资源
    引用计数同意对一个类的多次使用

    则我们通常在下列情况下考虑结构体:
    用来封装少量相关简单数据值
    估计数据传递会被拷贝而不是引用
    结构体中的值类型属性也会被拷贝
    不须要继承或被继承特征和行为

    集合类型的赋值和拷贝行为


    上面说到了值类型和引用类型。在Swift中,集合类型字典和数组在后台均以结构体实现,可是他们的情况略微有些特殊。
    尽管通常值类型的赋值行为都是通过拷贝实现的,我们也不须要害怕过多使用内存而带来的性能问题。Swift会管理全部的值拷贝以确保性能最优化。

    字典的赋值和拷贝行为

    字典的key/value中。若其为值类型则拷贝值。引用类型则拷贝引用。


    数组的赋值和拷贝行为


    相比字典数组要复杂的多,当操作数组内容时,数组能提供接近C语言的性能。而且保证拷贝仅仅有在必要时发生。

    那么必要时是什么时候呢?是改变数组长度的时候,比如调用了append(), insert(), remove()等函数。数组的拷贝才会发生。不改变时则属于引用传递。



    有的时候我们想确保数组的唯一性,这时能够调用unshare方法使其变成唯一拷贝。强制拷贝则使用copy方法。可是copy在不论什么情况下都会创建新的拷贝,而unshare则会确保唯一引用。



    在判定数组是否同样时我们也能够使用"==="来判定两个数组是否共用同样的空间或者元素。



    由于他们都非共用空间,所以返回都是false.



    有关闭包,枚举,结构体和类的基础知识都解说完成。

    欢迎勘误和讨论。


  • 相关阅读:
    二分查找
    苹果开发人员账号注冊流程
    cocos2d_android 瞬间动作
    Qt多线程学习:创建多线程
    Java模式(适配器模式)
    代理方法keywordAction与Fun的使用
    装饰者模式
    编写你自己的单点登录(SSO)服务
    4种Java引用浅解
    strtok和strtok_r
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7044547.html
Copyright © 2011-2022 走看看