Swift 与众不同的地方

switch(元组)

  • 特点

    • 其他语言中的switch语句只能比较离散的整形数据(字符可以转换成整数)
    • 但是swift中可以比较整数、浮点数、字符、字符串、和元组数据类型,而且它可以是离散的也可以使连续的范围
    • 而且在swift中case语句不需要显示的添加break语句,分支语句会自动进行跳转
    • 每个switch语句至少有一个default语句
  • switch中比较元组
    • 可以在元组中进行值绑定,来对某一个值进行判断
    • 可以使用where 语句对元组中的条件进行判断

跳转语句

  • break、contune、fallthrough、return

break

  • 主要用户循环体中终止循环
  • break的使用有两种方式

    break   //  没有标签
    break label // 添加标签
    // break语句中标签的使用
    label1: for var x = 0; x < 5; x++ { // 标签1label2: for var y = 0; y > 0; y-- { // 标签2if x == y {break label1 // 默认是跳出标签2,加上标签,可以直接跳出到指定循环}print("(x,y) = (\(x),\(y))")}
    }

continue

  • continue 的使用和break类似,可以使用标签指定继续的循环

    // continue语句中标签的使用
    label1: for var x = 0; x < 5; x++ { // 标签1label2: for var y = 0; y > 0; y-- { // 标签2if x == y {continue label1 // 默认是跳出标签2,加上标签,可以直接跳出到指定循环}print("(x,y) = (\(x),\(y))")}
    }

fallthrough

  • fallthrough是贯通语句,在swift的swiftch语句中case语句不能贯通,但是如果我们需要设置贯通语句,可以使用fallthrough语句
  • 在switch语句中case后fallthrough,会执行下一个case语句

函数

  • 参数传递

    • 外部参数名和内部参数名
    • 外部参数名可以在调用函数时显示出来
    func rectangle(W width:Int, H height:Int) -> Int {//  其中W\H是外部参数名,在外部调用这个方法时会显示出来,提示这个参数是神马意思// width\height 是内部参数,在函数内部调用使用return width * height
    }
    • 也可以让内部便令名变为外部变量名,使用字符 “#”
    func rectangle(#width:Int, #height:Int) -> Int{//  其中W\H是外部参数名,在外部调用这个方法时会显示出来,提示这个参数是神马意思// width\height 是内部参数,在函数内部调用使用return width * height
    }
  • 参数默认值

    func rectangle(#width:Int = 100, #height:Int = 100) -> Int {//  其中W\H是外部参数名,在外部调用这个方法时会显示出来,提示这个参数是神马意思// width\height 是内部参数,在函数内部调用使用return width * height
    }
  • 可变参数

    func sum(numbers: Double... ) -> Double {var total: Double = 0for num in numbers {total += num}return total
    }
  • 参数的引用传递
    • 在众多数据类型中,只有类是引用传递,其他的数据类型如整形、浮点型、布尔型、字符串、元组、集合、数据、枚举、结构体都是值传递。
    • 如果一定要把一个值传递的类型的数据变为引用传递模型的话,可使用关键字'inout'
    func rectangle(inout width:Int, increased:Int = 1 ) {width += increased
    }
    var value:Int = 10
    rectangle(&value) // 结果是11
    rectangle(&value,100) // 结果是111
  • 函数返回值
    • 特别之处是可以返回一个元组,表示多个值
    func rectangleArea(width:Double, increased:Double = 1 ) -> (area:Double,height:Double) //返回面积和高度
  • 函数类型
    • 函数类型包括函数参数类型和返回值类型
    • (Double, Double) -> Double //传入宽高,计算面积
    • 这个就是函数类型,函数类型可以作为其他函数的返回类型
    • 比如写一个通用的方法来计算更多种图形的面积,这时可以使用这个函数类型作为返回值
    • 函数类型还可以作为参数类型使用,可以直接使用返回值作为参数,然后可以在函数内部调用这个函数
  • 函数重载
    • 和C++中函数重载类似,但是在swift中函数返回值类型外部参数名 也可以作为不同函数的判断标准
  • 嵌套函数
    • 可以在函数内部定义并调用函数

泛型和泛型函数

  • 泛型就是在运行时才确定类型的一种机制,这个C++中的泛型如出一辙
  • 就是定义一个模板,使用多种场景
  • 函数参数或者返回值到运行时才能确定

        func add(a:Int, b:Int) -> Int{return a + b}func add(a:Double, b:Double) -> Double{return a + b}
  • 如果用泛型计算两个数的和,可以写成下面这个样

        func add<T>)(a:T, b:T) -> T {return a + b}// 或者指定多重类型func add<T,U>(a:T, b:U) -> T {return a + T(b)} 
  • 如果比较两个类型的话,那么必须要遵守Comparable协议才可以

        func isEquals<T: Comparable>(a:T, b:T) -> Bool {return (a == b)}

闭包

  • 闭包是自包含的匿名函数代码块,可以作为表达式、函数参数和函数返回值。

    { (参数列表) -> 返回值类型 in语句组
    }

使用举例

  • 完整版本

    {(a:Int, b:Int) -> Int in return a + b}
  • 简化版本 {a,b in return a + b }
    • 如果闭包中只有一条return语句,那么return 语句可以省略{a,b in a + b }
    • 缩写参数名称 {$0 + $1} swift会自动推到出参数类型,$0表示第一个参数,$1表示第二个参数
    • 闭包作为返回值,直接可以为变量和常量赋值
     let reslut:Int = {(a:Int, b:Int) -> Int in return a + b}(10, 89)
  • 捕获上下文中的变量和常量
    • 嵌套函数和闭包可以访问其所在上下文中的常量和变量,这就是捕获值。即便是定义这些常量或变量的作用域已经不存在,嵌套函数或闭包仍然可以在函数体内或闭包内修改或引用这些值。

swift中的面向对象

枚举

  • swift中枚举可以存储多种数据类型,并不是真正的整数

        // 默认并不是整形enum WeekDays {     case Mondaycase Tuesdaycase Wednesdaycase Thursdaycase Friday}// 简写enum WeekDays {case Monday, Tuesday, Wednesday, Thursday, Friday}
  • 注意:在switch中使用枚举类型时,语句中的case必须全部包含枚举中所有成员,不能多也不能少,包括default语句。
  • 指定没枚举的原始值,可以是字符、字符串、整数、浮点数等

        // 指定枚举的原始值enum WeekDays: Int {case Monday = 0case Tuesdaycase Wednesdaycase Thursdaycase Friday}
  • 原始值使用的话,要用到函数 toRaw()fromRaw()

结构体

  • swift中结构体和类非常类似,可以定义成员变量和方法
  • 结构体不具备继承、运行时强制类型转换、析构函数、引用计数等
  • 除了对象是引用传递,其他数据类型都是值传递,引用之间的比较可以使用 ‘===’ 和 ‘!===’

可选类型和可选链

  • “?” 和 "!"

    • 不确定一个变量是否有值,可以加 ?
  • 可选绑定 : 如果赋值不为nil的话就执行if语句

    if let result: Double? = divide(100,0) {print("success")
    }
    else {print("failure")
    }
  • 强制拆封 : 使用 ! 来强制拆封

    let result: Double? = divide(100,0)print(result!) 
  • 可选链
    • 一些可选类型内部包含其他可选类型,然后产生层级关系。

访问限定

  • 访问范围的界定主要有:模块和源文件
  • 访问级别:public、internal、private
  • 可修饰类、结构体、枚举等面向对象的类型,还可以修饰变量、常量、下标、元组、函数、属性等。以上这些统称“实体”
  • 使用方式
    • public : 只要在import进所在模块,那么在该模块中都可访问
    • internal : 只能访问自己模块的任何internal实体,不能访问其他模块中的internal实体,默认就是internal修饰符
    • private : 只能在当前源文件中访问的实体。
  • 设计原则
    • 如果是自己在本文件内部使用,就用默认的就行。
    • 如果是开发第三方框架的话,那么一定要设计好访问级别,接口一定要public。其他的可以private

属性和下标

1、存储属性

  • 存储属性适用于类和结构体两种类型,包括常量属性(let)和变量属性(var

    • 在一个类中定义一个结构体对象属性或者类对象属性时就算是存储属性,可以指定默认值
  • 可以对存储属性进行延迟加载
  • 属性观察者
    • 使用在一般的存储属性和计算属性上
    • willSet 在设置新值之前调用
    • didSet 在设置新值之后马上调用
    var fullName: String {didSet {fullName = firstName + "." + secondName}

2、计算属性

  • 计算属性本身不存储数据,只从其他存储属性中获得数据。类、结构体、枚举都可以定义计算属性
  • 计算属性只能使用var修饰

    var firstName: String = "Jone"
    var secondName: String = "Hu"
    // 计算属性
    var fullName: String {get {return firstName + "." + secondName}set (newValue) {let names = newValue.componentsSeparatedByString(".")firstName = names[0]secondName = names[1]}
    }
  • 只读计算属性,只写set方法即可,这是可以省略set,直接return即可

    var firstName: String = "Jone"
    var secondName: String = "Hu"
    // 计算属性
    var fullName: String {return firstName + "." + secondName
    }

3、静态属性

  • 可以在类、结构体、枚举中定义静态属性

4、下标

  • 一些集合类型,可以使用下标访问

    /**
    *  定义二维数组,使用下标访问数组
    *  内部还是一个一维数组,不过展示给外界的时一个二维访问方式
    */
    struct DoubleArray {// 属性定义let rows: Intlet cols: Intvar grid: [Int]// 构造方法init(rows: Int, cols: Int) {self.rows = rowsself.cols = colsgrid = Array(count: rows * cols, repeatedValue: 0) // 利用泛型创建一个数组}// 下标定义subscript(row: Int, col: Int) -> Int {get {return grid[row * col + col]}set (newValue) {grid[row * col + col] = newValue}}
    }// 使用二维数组
    var arr2 = DoubleArray(rows: 10, cols: 10)// 初始化二维数组
    for var i = 0; i < 10; i++ {for var j = 0; j < 10; j++ {arr2[i,j] = i * j}
    }// 输出二维数组
    for var i = 0; i < 10; i++ {for var j = 0; j < 10; j++ {print("\t \(arr2[i,j])")}print("\n")
    }

方法

  • 类、结构体、枚举中都可以定义方法
  • 这里主要说结构体和枚举中方法的定义
    • 默认情况下,结构体和枚举中的方法是不能修改属性的
    • 如果要修改属性的话,需要在方法之前加关键字 mutating ,称之为变异方法

静态方法

  • 结构体和枚举中静态方法用static,类中静态方法使用class
  • 1、结构体中的静态方法
    • 不能访问示例属性和示例方法
    /**
    *  结构体中的静态方法
    */
    struct Account {var owner: String = "Jack"static var interestRate: Double = 0.668// 静态方法static func interestRateBy(amount: Double) -> Double  {return interestRate * amount}func messageWith(amount: Double) -> String {let interest  = Account.interestRateBy(amount)return "\(self.owner) 的利息是 \(interest)"}
    }
    // 调用静态方法
    print(Account.interestRateBy(10_000.00))
    //
    var myAccount = Account()
    print(myAccount.messageWith(10_000))
  • 2、枚举中的静态方法
    • 不能访问示例属性和示例方法
    /// 枚举中的静态方法
    enum Account1 {case 中国银行case 中国工商银行case 中国建设银行case 中国农业因银行static var interestRate: Double = 0.669// 静态方法定义static func interestBy(amount: Double) -> Double {return interestRate * amount}
    }
    // 静态方法的调用
    print(Account1.interestBy(10_000.00))
  • 3、类中的静态方法
    • 不能访问示例属性和示例方法
    /// 类中的静态方法,使用关键字class
    class Account2 {var ower: String = "Jack"class func interestBy(amount: Double) -> Double {return 0.889 * amount}
    }
    // 调用静态方法
    print(Account2.interestBy(10_000.00))

构造和析构

  • 只有类和结构体才有构造init()和析构函数deinit
  • 在创建实例过程中需要一些初始化操作,这个过程称为构造
  • 在实例最后被释放的过程中,需要清楚资源,这个过程称为析构
  • 注意: 构造器 可以重载,没有返回值

构造器

  • 构造器主做一些属性的初始化操作
  • 如果不写init方法,那么会自动生成一个空的init构造器
  • 如果有继承关系,要先调用父类的构造器
  • 横向代理与向上代理
    • 横向代理:构造器调用发生在本类内部,添加convenience关键字即可作为便利构造器,便利构造器必须调用本类内部的其他构造器
    • 向上代理:有继承关系,就先调用父类的构造器

      析构器

  • 析构器只作用于类
  • 析构器没有返回值,没有参数,不能重载

继承

  • swift单继承
  • 重写属性、下标以及方法
  • 重写父类的方法使用override
  • 终止属性或者方法的继承可以使用 final
  • 类型检查 is as Any AnyObject
    • is 类型判断
    • as 类型转换
    • Any 任何类型,包括类和其他数据类型
    • AnyObject 任何类

      扩展和协议

扩展extension

  • 扩展的类型可以使类、结构体、枚举
  • 扩展可以增加属性和方法
  • 扩展计算属性、方法、构造器、下标
  • 注意:扩展类的构造器的时只能增加遍历构造器,指定构造器和析构器只能由源类型指定

协议 protocol

  • 类似C++中的纯虚类
  • 可以定义属性和方法
  • 协议可以继承协议

swift内存管理

  • swift内存管理遵循ARC特性
  • 对引用类型进行引用计数,基本数据类型由系统管理

    循环引用问题

  • swift中解决循环引用由两种方式
    • 1、弱引用(weak reference
    • 2、无主引用(unowned reference)
  • 弱引用可以没有值,因此必须设置成可选类型
  • 无主引用适用于引用对象永远有值

闭包中的循环引用问题

  • 闭包中的循环引用的解决方法和上面的一样,使用弱引用和无主引用

    class Person {let firstName: String = "Jack"let secondName: String = "lu"/***  解决闭包强循环引用*/lazy var fullName: (String, String) -> String = {// [weak self] (firstName: String, secondName: String) -> String in[unowned self] (firstName: String, secondName: String) -> String inreturn firstName + secondName}
    }

OC与Swift

  • OC和swift可以混合开发

  • 1、swift 调用 OC
    • 桥接文件 "-Bridging-Header.h"
    • 在桥接文件中引入OC头文件即可
  • 2、OC调用swift
    • 包含头文件,这个头文件命名样式 "-swift.h"
    • 在swift源文件中要把类声明为 @objc
    • 这时新建swift类就不需要选择新建swift文件,而是选择Cocoa Touch Class,然后选择语言类型位swift

转载于:https://www.cnblogs.com/songliquan/p/4856700.html

Swift 与众不同的地方相关推荐

  1. 为什么python会火?看到这个几个与众不同的地方你就懂了!

    Python 诞生之初就被誉为最容易上手的编程语言.进入火热的 AI 人工智能时代后,它也逐渐取代 Java,成为编程界的头牌语言. 下面我们来看看python相对于其他语言,有啥与众不同的地方.私信 ...

  2. Arnold渲染器与众不同的地方在于何处?

    从事影视动画行业的朋友,一定对Arnold这款全局照明渲染软件不陌生,它是一款高级的.跨平台的渲染器. 软件用户在使用 Arnold 时,可执行的操作有: 1.通过即取即用的工具管理复杂的项目. 在 ...

  3. iOS新的旅程之Swift语言的学习

    好久都没有来这个熟悉而又陌生的地方啦, 想想已经有两三个月了吧,不过我相信以后还是会经常来的啦,因为忙碌的学习已经过去啦,剩下的就是要好好的总结好好的复习了,好好的熟悉下我们之前学习的知识点,将他们有 ...

  4. 网易漫画Swift混编实践

    \ 本文为『移动前线』群在4月8日的分享总结整理而成,转载请注明来自『移动开发前线』公众号.\ 嘉宾介绍 \ 胡波,来自于网易杭州研究院,之前在网易杭研移动应用部参与网易公开课/网易看游戏/网易云阅读 ...

  5. Swift Web 开发之 Vapor - 入门(一)

    简介 Vapor 是一个基于纯 Swift 构建出的 Web 开发框架,目前可以运行在 macOS 和 Ubuntu ,用于构建出漂亮易用的网站或者 API 服务. 官方称是用的最多的 Swift w ...

  6. Swift 3有什么新功能?

    介绍 今年9月,Apple正式发布了其新编程语言Swift 3的最新版本.就像去年的Swift 2一样,该版本包含许多新功能和改进,这使使用Swift进行编程变得更加出色! 从8.0版开始,Xcode ...

  7. IOS开发入门之一——Swift语言基础

    需要iOS视频资料可以加我微信: 1914532832  验证信息请注明:IOS开发 很多新人对IOS开发很迷茫,不知道从何下手?看完本系列,你将会觉得IOS入门其实很简单.要学习IOS开发,当然是先 ...

  8. uber_Uber是如何制成的

    uber by Dmytro Brovkin 由Dmytro Brovkin Uber是如何制成的 (How Uber was made) Uber has transformed the world ...

  9. 黑客马拉松 招募_我如何赢得第一次黑客马拉松-研究,设计和编码的2个狂野日子

    黑客马拉松 招募 I had no coding or engineering background. I studied biology in college, with no clue about ...

最新文章

  1. struts.xml web.xml配置正常,访问action时出现404
  2. 清华博士接亲被要求现场写代码,网友:真是面向对象编程!
  3. jquery中文参考文档
  4. PAT甲级1092 To Buy or Not to Buy :[C++题解]哈希表
  5. Linux下的删除命令
  6. catia曲面扫掠命令详解_Mastercam快捷键命令,附中英文功能讲解!值得收藏!
  7. 前端学习(570):margin负值下的等高布局
  8. CAFFE(FAQ.2):Ubuntu 配置caffe 框架之数据库读取,错误解决:ImportError: No module named leveldb解决办法...
  9. Linux下安装 卸载mysql57 msyql80
  10. [原创]WCF技术剖析之三:如何进行基于非HTTP的IIS服务寄宿
  11. Docker镜像、容器的理解和使用方法
  12. 关于跳转 + 传递消息,
  13. 纽微特纪事:改个字串,竟然成了“二期工作”,还拖了几个月
  14. html hr 垂直居中,常见的CSS水平垂直居中设置
  15. SolidWorks用鼠标中键控制模型的旋转、缩放和平移
  16. win7系统下装ubantu
  17. git push -u origin XXX 报错
  18. 从数据库中读取经纬度,在google map 上进行标注(一)
  19. 2022.02.14【读书笔记】|基于深度学习的生命科学 第2章 深度学习概论(上)
  20. Linux第五次学习笔记

热门文章

  1. sqlserver无法启动端口冲突解决方法
  2. 去掉WINDOWS SERVER 开机按CTRL+ALT+DEL登陆的方法
  3. Airbnb如何简化1000多位工程师的Kubernetes工作流程?
  4. 【leetcode】Remove Duplicates from Sorted Array
  5. 团队开发——第一次冲刺第7天
  6. 关于FlasCC(Adobe Flash C/C++ Compiler)
  7. Linux利用list_head结构实现双向链表
  8. datagridview自动保存修改数据
  9. alin39048错误原因_支付宝支付ALIN10146错误
  10. Linux下高速缓存DNS的配置