swift语言学习总结

  1. Var 表示变量, let表示常量。
  2. 数组和map, 都用中括号[].可以直接赋值。可以用下标或键访问。

var shoppingList = ["catfish", "water", "tulips", "blue paint”]//最后一个可以加逗号。

shoppingList[1] = "bottle of water"

var occupations = [

    "Malcolm": "Captain",

    "Kaylee": "Mechanic",

]

空数组就赋[], 而空map 就赋[:]。有点无语。

  1. 字符串处理。用\() 可以处理字符串的变量插入。

let apples = 3

let oranges = 5

let appleSummary = "I have \(apples) apples."

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

三个双引号(""")来包含多行字符串内容

4.swift也有可空类型, String?, 同样用!表示非空。但是不像其他语言用null表示空, 而是nil。非要别出新裁。

双??的用法和dart一样。

  1. Switch语法,支持任何类型的case。而且不需要用break, 找到case后执行完自己会退出switch,不会往下执行。当需要提前退出时,也可以用break。多个case可以用逗号合并。还有:区别匹配case 100..<1000;元组匹配(1,1)。  Case let Where语句。fallthrough可以继续下一个case。
  2. 条件语句和循环语句都允许不用包含在括号里面, if, for-in, while,repeat-while。
  3. repeat-while就是do-while
  4. 在for循环中,..< 来表示下标范围, 但不包含上界, 如果包含的就用…

var total = 0

for i in 0..<4 {// 0到3

    total += i

}

for i in 0..<4 {// 0到4

    total += i

}

  1. 强制类型转换是用转换后的类型加上括号。Int(3.14)转换后就是3.
  2. 可以定义类名的别名,typealias。   typealias AudioSample = Int   AudioSample就可以当Int来使用了。这种傻逼功能还是少用。让人想起c/c++宏定义魔窟。
  3. 元组。 (name:type, name:type),和kotlin的很像。let http200Status = (statusCode: 200, description: "OK”)。针对函数返回值很有用的。

  1. 可选绑定 if let的用法。 把一个可控类型的参数赋值给一个正常参数,如果可控参数有值,就赋值成功,同时if语句是true, 在if语句里面就不需要用!来表示非空了。还可以多个一起,只要一个不成功就是false。

if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {

}

  1. 运算符方面,包含了java的所有功能, 包括三元运算符是一样的,这点很好比kotlin强。另外,增加了??和单双边运算符[…]
  2. 字符串方面和java大同小异。 字符串插值\(), 去语义#”  ”#. 字符串拼接也是+,和java一样。
  3. 数组方面。 数组类型定义是这样:[type],由于有类型推断,也可以不用写。 支持两个数组相加后合并到一起。

15.数组修改,追加append, 删除remove, 追加另外一个数组+=, 插入insert, 判空isEmpty。按照方法来说,应该是链表实现的。

16.集合set,方法和java差不多。

  1. Guard关键词,和 if let相识,只是在不满足时会跟一个else。
  2. 关于函数,总体和kotlin一样。但返回是用->表示;在函数参数前可以加标签注释, 如果参数名前加了下划线_j就不能加了;动态参数用…. ;当函数体只有一条代码,返回时,可以不带return;函数类型的使用也和kotlin类似。
  3. 闭包整体和kotlin的一样。闭包是引用类型。

reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 } )

尾随方式

reversedNames = names.sorted(){ (s1, s2) -> Bool in return s1 > s2 }

可以用$0,$1…,来特指参数。 如果其中一个不用,那用_替代。

reversedNames = names.sorted(){ return $0>$1 }

可以把括号也省掉

reversedNames = names.sorted{ return $0>$1 }

如果闭包在最后,那么也可以是尾随闭包。

    func test1( values:String, process:()->Bool){

    }

        test1(values:""){true}

闭包逃逸,就是说闭包传到函数里面,但是没有执行闭包, 只是把闭包引用给了别人。要加一个 @escaping

var completionHandlers: [() -> Void] = []

func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {

    completionHandlers.append(completionHandler)

}

自动闭包就是函数定义。

let customerProvider = { customersInLine.remove(at: 0) } //定义了一个函数;

在函数中直接写执行代码没有括号。要加 @autoclosure

func serve(customer customerProvider: @autoclosure () -> String) {

    print("Now serving \(customerProvider())!")

}

serve(customer: customersInLine.remove(at: 0))

可以即是自动闭包又可以是逃役闭包,

var customerProviders: [() -> String] = []

func collectCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {

    customerProviders.append(customerProvider)

}

  1. 枚举,成员前要加case。

两种定义方式:

enum CompassPoint {

    case north

    case south

    case east

    case west

}

enum Planet {

    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune

}

var directionToHead = CompassPoint.west

一旦 directionToHead 被声明或者被推断出为 CompassPoint 类型,可以间断成这样:

directionToHead = .east

遍历枚举成员:

enum Beverage: CaseIterable {

    case coffee, tea, juice

}

let numberOfChoices = Beverage.allCases.count

枚举关联值,这个功能很好,就是附带信息用的。和kotlin的sealed class有点像,就是没有执行方法。比如把异常的code和error情况塞到里面。

enum Barcode {

    case upc(Int, Int, Int, Int)

    case qrCode(String)

}

var productBarcode = Barcode.upc(8, 85909, 51226, 3)

使用时如下:

switch productBarcode {

case .upc(let numberSystem, let manufacturer, let product, let check):

    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")

case .qrCode(let productCode):

    print("QR code: \(productCode).")

}

枚举初始值。枚举值可以是任何类型的值,可以是int/double/String。

和C#一样,会递增。如果不设值第一个默认是0

enum Planet: Int {

    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune

}

enum CompassPoint: String {

    case north, south, east, west

}

let earthsOrder = Planet.earth.rawValue

// earthsOrder 值为 3

let sunsetDirection = CompassPoint.west.rawValue

// sunsetDirection 值为 "west"

前面提到“枚举值可以是任何类型的值”。所以也可以是枚举自身啊。所以这里就有递归问题了。

而且递归是支持的,用关键字:indirect

enum ArithmeticExpression {

    case number(Int)

    indirect case addition(ArithmeticExpression, ArithmeticExpression)

    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)

}

你也可以在枚举类型开头加上 indirect 关键字来表明它的所有成员都是可递归的:

indirect enum ArithmeticExpression {

    case number(Int)

    case addition(ArithmeticExpression, ArithmeticExpression)

    case multiplication(ArithmeticExpression, ArithmeticExpression)

}

例子:let five = ArithmeticExpression.number(5)

let four = ArithmeticExpression.number(4)

let sum = ArithmeticExpression.addition(five, four)

let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))

因为枚举的最终使用还是在选择语句上:

func evaluate(_ expression: ArithmeticExpression) -> Int {

    switch expression {

    case let .number(value):

        return value

    case let .addition(left, right):

        return evaluate(left) + evaluate(right)

    case let .multiplication(left, right):

        return evaluate(left) * evaluate(right)

    }

}

  1. 结构体struct。 swift还保留着struct。可能是内存回收机制缺陷导致的,便于一些情况下的回收。还有就是速度更快一点,相当于是在栈上。

struct是值类型,所以赋值的时候是值拷贝,生成了另外一个struct实例。和类差异并不大。

和类相同的地方:

  • 定义属性用于存储值
  • 定义方法用于提供功能
  • 定义下标操作用于通过下标语法访问它们的值
  • 定义构造器用于设置初始值
  • 通过扩展以增加默认实现之外的功能
  • 遵循协议以提供某种标准功能

类还有如下的附加功能:

  • 继承允许一个类继承另一个类的特征
  • 类型转换允许在运行时检查和解释一个类实例的类型
  • 析构器允许一个类实例释放任何其所被分配的资源
  • 引用计数允许对一个类的多次引用

类的恒等运算符

  • 相同(===)
  • 不相同(!==)

使用这两个运算符检测两个常量或者变量是否引用了同一个实例:

if tenEighty === alsoTenEighty {

    print("tenEighty and alsoTenEighty refer to the same VideoMode instance.")

}

  1. 属性。 分为存储属性和计算属性。 存储属性就是property,计算属性就是getter/setter方法。

变量用var,常量用let.

懒加载,用 lazy 来标示一个延时加载存储属性。必须声明成var, 因为是构造后才使用, 不能是let。

但是swift的懒加载不支持多线程安全。

class DataImporter {

    /*

    DataImporter 是一个负责将外部文件中的数据导入的类。

    这个类的初始化会消耗不少时间。

    */

    var fileName = "data.txt"

    // 这里会提供数据导入功能

}

class DataManager {

    lazy var importer = DataImporter()

    var data = [String]()

    // 这里会提供数据管理功能

}

计算属性getter/setter, 下面是完整的方式:

struct Point {

    var x = 0.0, y = 0.0

}

struct Size {

    var width = 0.0, height = 0.0

}

struct Rect {

    var origin = Point()

    var size = Size()

    var center: Point {

        get {

            let centerX = origin.x + (size.width / 2)

            let centerY = origin.y + (size.height / 2)

            return Point(x: centerX, y: centerY)

        }

        set(newCenter) {

            origin.x = newCenter.x - (size.width / 2)

            origin.y = newCenter.y - (size.height / 2)

        }

    }

}

简化Get, 当单行代码时。可以省去return。

简化Set, 用newValue替代设置值。

struct CompactRect {

    var origin = Point()

    var size = Size()

    var center: Point {

        get {

            Point(x: origin.x + (size.width / 2),

                  y: origin.y + (size.height / 2))

        }

        set {

            origin.x = newValue.x - (size.width / 2)

            origin.y = newValue.y - (size.height / 2)

        }

    }

}

当只有getter时,可以简化, 省去get关键字和{}。

struct Cuboid {

    var width = 0.0, height = 0.0, depth = 0.0

    var volume: Double {

        return width * height * depth

    }

}

属性观察器

  • willSet 在新的值被设置之前调用
  • didSet 在新的值被设置之后调用

即使新值和当前值相同的时候也不例外。

在父类初始化方法调用之后,在子类构造器中给父类的属性赋值时,会调用父类属性的 willSet 和 didSet 观察器。而在父类初始化方法调用之前,给子类的属性赋值时不会调用子类属性的观察器。

class StepCounter {

    var totalSteps: Int = 0 {

        willSet(newTotalSteps) {

            print("将 totalSteps 的值设置为 \(newTotalSteps)")

        }

        didSet {

            if totalSteps > oldValue  {

                print("增加了 \(totalSteps - oldValue) 步")

            }

        }

    }

}

属性包装器,就是getter/setter的套用模版。可以是结构体也可以是类。

@propertyWrapper

struct SmallNumber {

    private var maximum: Int

    private var number: Int

    var wrappedValue: Int {

        get { return number }

        set { number = min(newValue, maximum) }

    }

    init() {

        maximum = 12

        number = 0

    }

    init(wrappedValue: Int) {

        maximum = 12

        number = min(wrappedValue, maximum)

    }

    init(wrappedValue: Int, maximum: Int) {

        self.maximum = maximum

        number = min(wrappedValue, maximum)

    }

}

struct NarrowRectangle {

    @SmallNumber(wrappedValue: 2, maximum: 5) var height: Int

    @SmallNumber(wrappedValue: 3, maximum: 4) var width: Int

}

这样height最大值就是5,width最大值就是4。

  1. 结构体/类的下标,枚举也可以。定义下标使用 subscript 关键字。

一维数组

subscript(index: Int) -> Int {

    get {

      // 返回一个适当的 Int 类型的值

    }

    set(newValue) {

      // 执行适当的赋值操作

    }

}

二维数组:

subscript(row: Int, column: Int) -> Int {

    get {

      // 返回一个适当的 Int 类型的值

    }

    set(newValue) {

      // 执行适当的赋值操作

    }

}

  1. 继承。 用:继承, 用self替代this, 调用超类方法用super。重写在func前加override。防止重写用final。
  2. 构造函数。全是用init()来替代类名构造, 要么已经初始化好了,直接class()。可选属性在init里可以不初始化。

常量的初始化,可延迟到构造函数里。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/581156.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文讲解Android车载系统camera架构 - EVS

Android的camera开发中&#xff0c;使用最多的是camera2 以及现在Google主推的cameraX 架构&#xff0c;而这两个架构主要针对的是手机移动端上camera的流程。 而今天介绍的EVS(Exterior View System)架构是不同于camera2上的手机架构&#xff0c;针对Automotive的版本&#x…

【源码阅读】 Golang中的database/sql库源码探究

Note&#xff1a;文章待完结 文章目录 前言一、整体目录结构二、driver包1、驱动相关driver.Driver2、驱动连接&#xff1a;driver.Conn3、预处理结构&#xff1a;Stmt4、执行结果 driver.Result5、查询结果&#xff1a;driver.Rows6、driver.RowsAffected7、driver.Value8、Va…

vue-quill-editor富文本插件控制字数显示

最终效果 富文本编辑框&#xff0c;只统计内容&#xff0c;不包含标签以及样式&#xff0c;超出最大字数限制提示。 具体代码 html <div class"relative"><quillEditorv-model"form.nutriSuggestion"ref"myQuillEditor7":options&quo…

03-JAVA设计模式-策略模式

策略模式 什么是策略模式 策略模式&#xff08;Strategy Pattern&#xff09;是行为设计模式之一&#xff0c;它使你能在运行时改变对象的行为。在策略模式中&#xff0c;一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为模式。 在策略模式中&#xff0c;…

uniapp微信小程序开发踩坑日记:由于图表数据渲染不出来,我第一次在项目中用watch函数监听数据变化

一、发现问题 在我们团队自己开发的微信小程序中&#xff0c;引入了Echarts图表库 然后突然有一天&#xff0c;后端队友反应图表渲染有问题。后面我去试了一下&#xff0c;确实20次里面必有一次数据渲染不出来 断定代码没问题&#xff0c;于是我们将其鉴定为玄学 二、问题原因…

【GitHub】主页简历优化

【github主页】优化简历 写在最前面一、新建秘密仓库二、插件卡片配置1、仓库状态统计2、Most used languages&#xff08;GitHub 常用语言统计&#xff09;使用细则 3、Visitor Badge&#xff08;GitHub 访客徽章&#xff09;4、社交统计5、打字特效6、省略展示小猫 &#x1f…

UDP和TCP(传输层)

这里写目录标题 UDPUDP的基本特点UDP协议报文格式 TCPTCP协议报文格式TCP特点可靠传输实现机制确认应答超时重传数据丢了应答报文丢了 小结 UDP UDP的基本特点 无连接不可靠传输面向数据报全双工 UDP协议报文格式 2个字节有效范围(无符号): 0 ~ 65535(2^16 - 1). 2个字节有效范…

用数据检验函数正确性,matlab2C

数据存取格式 filename1 g.txt; fid1 fopen(filename1,w); for i 1 : length(g)for j1:size(g,2)if(j1)fprintf(fid1,{%.16f,,g(i,j)); elseif(j>1&&j<151)fprintf(fid1,%.16f,,g(i,j)); elsefprintf(fid1,%.16f},\n,g(i,j));endend%fprintf(fid1,\n…

如何用Python语言实现远程控制4路控制器/断路器

如何用Python语言实现远程控制4路控制器/断路器呢&#xff1f; 本文描述了使用Python语言调用HTTP接口&#xff0c;实现控制4路控制器/断路器&#xff0c;支持4路输出&#xff0c;均可独立控制&#xff0c;可接入各种电器。 可选用产品&#xff1a;可根据实际场景需求&#xf…

Spring Web MVC入门(3)——响应

目录 一、返回静态页面 RestController 和 Controller之间的关联和区别 二、返回数据ResponseBody ResponseBody作用在类和方法的情况 三、返回HTML代码片段 响应中的Content-Type常见的取值&#xff1a; 四、返回JSON 五、设置状态码 六、设置Header 1、设置Content…

2024李卜常识开天斧

2024年&#xff0c;李卜常识开天斧课程以其独特的魅力吸引了众多学子。这门课程如同开天辟地的神斧&#xff0c;帮助我们打开常识知识的大门&#xff0c;引领我们走进一个全新的学习世界。在李卜老师的悉心指导下&#xff0c;我们逐渐掌握了各种常识知识&#xff0c;拓宽了视野…

leaftjs+turfjs+idw纯前端实现等值面绘图+九段线

最近有个绘制等值面图的需求。我们一般的实现路径是&#xff1a; 1.后台绘图&#xff0c;用surfer绘制好&#xff0c;给前端调用叠加到地图。 2.后台用python绘图&#xff0c;绘制好给前端调用&#xff0c;叠加到地图。 3.后台进行插值计算、地图裁剪、最终生成geojson文件或…

VS2019配合QT5.9开发IRayAT430相机SDK

环境配置 VS2019 QT5.9 编译器版本 MSVC2017_64添加系统环境变量&#xff08;完毕后重启电脑&#xff09; 从VS2019中下载Qt插件 从VS2019中添加单个编译组件 上述操作完成后用VS打开工程文件&#xff0c;工程文件地址 &#xff1a; C:\Users\86173\Desktop\IRCNETSDK_W…

初识 Linux

一、基础命令 0、 ls cd cat pwd 当前工作目录 find -name 测试.py 查找文件 grep "学院" 测试.py 查找字符串 "学院" 在文件 测试.py 中位置&#xff0c;输出所在的 行 1、重定向器 echo "Hello Kali Linux!" > Hello 创建 文件 Hel…

openssl3.2 - exp - 使用默认的函数宏,在release版中也会引入__FILE__

文章目录 openssl3.2 - exp - 使用默认的函数宏&#xff0c;在release版中也会引入__FILE__概述笔记验证是否__FILE__在release版下也能用&#xff1f;将openssl编译成release版的&#xff0c;看看CRYPTO_free()是否只需要一个参数就行&#xff1f;将工程中的openssl相关的库换…

stream中的foreach,allMatch,noneMatch,anyMatch的基本使用

1.1foreach遍历集合元素 1.2anyMatch()的使用 结论:上边使用foreach循环遍历和使用anyMatch()的作用相同 2.allMatch() 2.1初级使用 2.2进级使用 3.noneMatch()使用

Python 实现视频去抖动技术

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 视频去抖动是视频处理中的一项重要技术&#xff0c;它可以有效地减少视频中由于相机震动或手…

华为matebook 14安装ubuntu双系统

一、准备u盘 首先格式化u盘(选择FAT32) 二、确认电脑类型 键盘按下win+r(win:开始键/也就是Windows的标志那个键),在输入框内输入msinfo32后,回车确认 确定自己电脑 硬盘 的类型: 在显示屏下方的搜索框内搜索“计算机管理” 点击进入后,再点击左边列表内的“磁…

拉普拉斯IPO:荣获国家级专精特新和国家级制造业单项冠军殊荣

近期&#xff0c;拉普拉斯荣获国家级专精特新和国家级制造业单项冠军的殊荣&#xff0c;这无疑是对其在技术和发展方面的肯定。这些荣誉证明了拉普拉斯在光伏行业的卓越表现和持续创新&#xff0c;以及其在国内制造业中的领先地位&#xff0c;进一步彰显了拉普拉斯在技术研发和…

智慧浪潮下的产业园区:洞察智慧化转型如何打造高效、绿色、安全的新园区

目录 一、引言 二、智慧化转型的内涵与价值 三、打造高效园区的智慧化策略 1、建设智能化基础设施 2、推广智能化应用 3、构建智慧化服务平台 四、实现绿色园区的智慧化途径 1、推动绿色能源应用 2、实施绿色建筑设计 3、加强环境监测与治理 五、保障园区安全的智慧…
最新文章