Swift之旅_Language Guide1

最近抽空阅读了swift官方文档的Language Guide部分小节,下面记录一些知识盲点和个人认为比较有用的东西。


The Basics

第一个小节主要讲解了一些基本的东西,如var let等。也有一些知识点可以记录一下吧。

  • typealias

相当于oc里的tyepdef吧,可以用来取别名。

typealias AudioSample = UInt16
  • optional & nil

Swift’s nil isn’t the same as nil in Objective-C. In Objective-C, nil is a pointer to a nonexistent object. In Swift, nil isn’t a pointer—it’s the absence of a value of a certain type. Optionals of any type can be set to nil, not just object types.

大概的意思是说oc里的nil是指向了一个不存在的对象,而在swift中,nil不是指针,它是一个确定类型的缺失(= =蹩脚的英文),任何可选类型可以设置成nil,不只是对象类型。网上也有很多资料都介绍过可选类型,可选其实就是对某个类型进行了一层包装,里面包含了some和none,none就是这个nil,some就是具体的值。

  • assert:断言

大部分用来调试使用,类似guard,但是不符合条件程序会直接退出。

let age = -3
assert(age >= 0, "A person's age can't be less than zero.")
  • Error handle

异常处理,不过目前只在调用别人的api的时候用到过= =。

do {
    try caThrowAnError(age: 1000)
} catch AgeEorror.negative {
    print(AgeEorror.negative.rawValue)
} catch AgeEorror.tooLarge {
    print(AgeEorror.tooLarge.rawValue)
} catch {
    print("未知错误~")
}
enum AgeEorror: String, Error {
    case negative = "输入的年龄不能是负数!"
    case tooLarge = "不可能活那么久!"
}
func caThrowAnError(age: Int) throws {
    if age < 0 {
        throw AgeEorror.negative
    } else if age > 200 {
        throw AgeEorror.tooLarge
    }
}

这里结合枚举使用,抛出的错误类型必须遵循Error协议。


Basic Operators

这一小节比较简单,讲解了大部分操作符。相信有点编程基础的应该都会一眼带过,但也抽两个知识点意思意思吧!

  • ??

这个操作符在平时开发中使用还是非常频繁的,至少本人平时经常使用,有点像是三目运算符的感觉。

var a: Int?
let b = a ?? 0

如上代码,大致的意思就是假设a有值,即a不为nil的时候会把a赋值给b,如果a为nil则把0赋值给b。

  • 区间运算符[...]

这个操作符在遍历集合等场景使用较多。

let names = ["1","2","3","4","5"]
for name in names[...3] {
    print(name)
}

没错,就是你心里想的那样,遍历第0-3个元素,也可以加入<操作符,如[..<3]表示遍历第0,1,2个元素。


Strings and Characters

这一小节主要是讲解了Swift中的字符串,有几个知识点在上一篇文章Swift之旅_Welcome to Swift有提到过,主要是一个字符串可以用”””来表示多行,还有新增了一个Substring类型,具体的可以参考上一篇文章。


Collection Types

这一小节讲解的是Swift中的集合类型,主要是Array,Dictionary,Set。都比较简单,而且Swift中用起来很方便。但是因为Set平时用的很少,我就着重看了一下。

A type must be hashable in order to be stored in a set—that is, the type must provide a way to compute a hash value for itself. A hash value is an Int value that is the same for all objects that compare equally, such that if a == b, it follows that a.hashValue == b.hashValue.

Set是一个无序不重复的集合,Set中的元素必须是可哈希的。直接一直不知道哈希是什么鬼。最近一次学习的时候知道了哈希其实就是一个单向散列函数。单项散列函数可以将一串数据计算得到一个独一无二的值,所以也不难理解为啥Set中的元素必须是可哈希的了,因为Set是不重复的。


Set.png

Set集合中一些常用的操作和对应的效果,官方文档中的这幅图非常形象。


Control Flow

控制流,讲解了一些循环和控制语句。

  • for循环

常见的都很简单,不过文档中倒是提到了一种比较特别的循环方式,可以以一个数的倍数进行循环:

let minutes = 60
let minuteInterval = 5
for tickMark in stride(from: 0, to: minutes, by: minuteInterval) {
    // render the tick mark every 5 minutes (0, 5, 10, 15 ... 45, 50, 55)
}

//以下写法可以到达hours,相当于小于等于吧
let hours = 12
let hourInterval = 3
for tickMark in stride(from: 3, through: hours, by: hourInterval) {
    // render the tick mark every 3 hours (3, 6, 9, 12)
}

此外我们都知道Swift中的switch语句是不用手动写break的,Swift也提供了一个修饰符可以让switch像c一样, fallthrough,这个修饰符可以让swift的switch语句匹配到对应的值之后继续向下落。

let a = 5
switch a {
    case 5,6,7,8,9:
        print("case 1")
        fallthrough
    case 1,2,3,4,5:
        print("case 2")
        fallthrough
    default:
        print("default")
}

Functions

这个小节就比较重要了,讲解的是Swift中的函数。

  • Variadic Parameters-可变参数

可变参数在绝对大多数开发语言中都存在,Swift也不列外。Swift中使用可变参数也是非常简单。

func arithmeticMean(_ numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8.25, 18.75)
// returns 10.0, which is the arithmetic mean of these three numbers
  • In-Out Parameters

在函数内部是无法直接更改参数的值的,或者这样说比较贴切,参数在函数内部是let形式的。若想要达到更改调用函数时传入的参数就需要用到inout这个修饰符。

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

Closures

block的作用和oc的大致相同,但是这里有多个注意点。

  • $0

Swift中的block可以直接用$0,$1...表示第1,2…参数,这样可以直接不用写明参数 和 in,这样写起来代码似乎是清爽了很多。

let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
reversedNames = names.sorted(by: { $0 > $1 } )
  • 可以直接将函数赋值给block

只要参数和返回值都相同,就可以直接将函数赋值给block

var block: (()->Int) = test
func test() -> Int {
    return 0
}
  • Escaping Closures

逃逸闭包,相信很多同学都碰到过Xcode自动帮你在函数参数中的block前面加上@escaping修饰符。

A closure is said to escape a function when the closure is passed as an argument to the function, but is called after the function returns. When you declare a function that takes a closure as one of its parameters, you can write @escaping before the parameter’s type to indicate that the closure is allowed to escape.

当闭包作为函数参数传递,但是是在函数返回后调用时,闭包被称为逃逸闭包。当你声明一个有闭包参数的函数时,你可以在参数前面写上@escaping表明闭包时允许逃逸的。

One way that a closure can escape is by being stored in a variable that is defined outside the function. As an example, many functions that start an asynchronous operation take a closure argument as a completion handler. The function returns after it starts the operation, but the closure isn’t called until the operation is completed—the closure needs to escape, to be called later.For example:

闭包可以逃避的一种方法是存储在函数之外定义的变量中。例如,启动异步操作的许多函数都使用闭包参数作为完成回调。函数在启动操作后返回,但是在操作完成之前不会调用闭包-为了可以延迟调用,闭包需要时可逃逸的。例如:

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

The someFunctionWithEscapingClosure(_:) function takes a closure as its argument and adds it to an array that’s declared outside the function. If you didn’t mark the parameter of this function with @escaping, you would get a compile-time error.

someFunctionWithEscapingClosure函数有一个闭包参数并且把它添加到了函数外部的一个数组中。如果你不在函数参数前面加上@ escaping,你会在编译的时候得到一个error。

其实大概的意思就是如果这个block是作为函数参数使用,并且是在函数执行完毕之后调用的,就需要在函数的block参数前面加上@escaping修饰符。其实这个大多时候XCode帮我们做了。大家了解一下就行。

  • @autoclosure

这个原文有点难翻译= =,直接上一段代码吧。

func test3(tBlock: @autoclosure ()->String) {
    print(tBlock())
}
test3(tBlock: "World")

大概意思就是和代码一样吧,感觉就是加上@autoclosure之后,调用函数的时候可以直接传入和闭包返回值相同类型的参数。


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 以下翻译自Apple官方文档,结合自己的理解记录下来。翻译基于 swift 3.0.1 原文地址 Closure...
    艺术农阅读 1,522评论 0 3
  • 86.复合 Cases 共享相同代码块的多个switch 分支 分支可以合并, 写在分支后用逗号分开。如果任何模式...
    无沣阅读 1,354评论 1 5
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,766评论 0 38
  • 表单上传 html: js: php:
    雨中追燕阅读 140评论 0 0
  • Double.Think “你爸现在话越来越多了”我妈私下里跟我说:“你爸上半辈子就知道埋头苦干,下半辈子都要成...
    Reese热热阅读 253评论 8 4