充满无争议协议的Swift协议:该如何正确使用

Swift2.2中的新变化浅析
Swift2.2已经更新了,这次更新去除了一些难用的语法还添加了一些缺失的特性,并且还弃用了一些有争议的语言特性。这篇文章将详细介绍Swift2.2中的一些主要的变化和一些细微的改变,还会展示一些实际的代码例子来让你更快的上手Swift2.2。
1. ++ 和 - - 被弃用了
Swift 2.2正式地弃用了++和- -操作符,意味着他们仍然可用但当你用到时会得到哦一条警告。弃用一般是完全移除的第一步,因此在这种情况下在Swift 3.0中这两个操作符将会被移除掉。
在使用这两个操作符的地方,你需要用+= 1和-= 1来替换掉他们。这两个操作符(+= -=)会一直存在,不会移除。
你可能会好奇为什么两个长期使用的操作符会被移除掉,尤其是他们存在于C、C#,以及调侃它的笑话 C++ 中时。下面列出了一些原因,但不是所有:
写++而非+= 1没有显著的节省时间虽然一旦你知道了它后用起来很容易,但是++对学习Swift的人来说并没有一个明确的含义,然而+=至少可以理解为&求和并赋值& C语言风格的for循环,这是++和&用的最多的地方,同样也被Swift弃用了,这也引出了我的下一点&
2. 传统的C风格for循环也被弃用了
对,你没看错:下面这种for循环将很快从Swift中完全移除掉:
for var i = 1; i &= 10; i += 1 {
print(&\(i) green bottles&)
之所以称之为C风格的for循环,因为他们作为类C语言的特性已经存在了很长时间,概念上甚至在C语言之前都已经很久了。
虽然Swift也是(大概吧)类C语言,但他有一些比传统的for循环更新的、更聪明的替代品。结果就是:这个结构在Swift 2.2 中被弃用了并且&会在将来版本的Swift中移除掉&。
注意:当前的弃用警告并没有提示会在Swift 3.0移除,但我怀疑他会的。
要替换这些旧的for循环,使用其中一个替代选择即可。例如,上面的green bottles代码可以使用range的循环来重写,就像这样:
for i in 1...10 {
print(&\(i) green bottles&)
记住,创建一个开始比结束值大的range是不对的,虽然你的代码会通过编译,但会在运行时崩溃掉。所以不要这么写:
for i in 10...1 {
print(&\(i) green bottles&)
而是应该写成这样:
for i in (1...10).reverse() {
print(&\(i) green bottles&)
另一个选择是直接使用数组的快速枚举,就像这样:
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for number in array {
print(&\(number) green bottles&)
3. 数组和其他的slice类型现在有removeFirst()函数了
removeFirst()方法对数组的操作一直很有用,但是直到现在一直缺少一个移除数组开始位置元素的对应方法。
好啦,添加了removeFirst()方法的Swift 2.2来拯救你了。这个方法会删除数组中的第一个元素并把它返回给你。
回头去看green bottles这个例子,你会发现两个坏习惯:第一,我使用了var而不是let,第二是打印了英语语法上的信息&一个绿瓶子们&。
这些都不是误写的,因为我要用它来演示removeFirst()了
var array = Array(1...10)
array.removeFirst()
for number in array {
print(&\(number) green bottles&)
注意:虽然removeLast()有一个返回可选的等效方法popLast(),removeFirst()并没有类似的可选等效方法。这意味着如果你对一个空数组调用这个方法,你的代码会crash掉
4. 现在你可以比较元组了(在合适的格式下)
元组是一系列由逗号分隔的值,元组的值可以包含参数名也可以不包含,比如下面这个:
let singer = (&Taylor&, &Swift&)
let alien = (&Justin& &Bieber&)
在旧版本的swift中,你不能比较两个元组的值,除非写一些笨重的代码,就像下面这样:
func == (t1: (T, T), t2: (T, T)) -& Bool {
return t1.0 == t2.0 && t1.1 == t2.1
需要些这样的样板代码的要求不是非常友好的,当然这也只对只有两个值的元组有效。在Swift 2.2 中,你不需要再写这样的代码了,因为元组可以直接进行比较了:
let singer = (&Taylor&, &Swift&)
let alien = (&Justin&, &Bieber&)
if singer == alien {
print(&Matching tuples!&)
print(&Non-matching tuples!&)
Swift 2.2的自动对比含两个元素的元组的效果就和我们刚写的函数功能一样。但它对六元元组同样适用,也就是有六个元素的元组。
至于为什么Swift的元组比较只支持到6元元组(而不是6百万),这里有两个原因。首先,每一次额外的比较都会需要调用Swift标准库中的更多代码。另外,使用这么大的元组就是代码有问题了。应该换成使用结构体。
你可以通过改变上面的两个元组来看看元组是怎么进行比较的:
let singer = (&Taylor&, 26)
let alien = (&Justin&, &Bieber&)
准备好接受Xcode长长的错误信息吧,但有趣的东西还在末尾呢:
note: overloads for '==' exist with these partially matching parameter lists: ......
((A, B), (A, B)), ((A, B, C), (A, B, C)), ((A, B, C, D), (A, B, C, D)), ((A, B, C, D, E), (A, B, C, D, E)), ((A, B, C, D, E, F), (A, B, C, D, E, F))
5. 元组的splat语法被弃用了
让我们在元组上多聊一会:另一个被弃用的特性是Swift自从2010年(对,Swift发布以前)就存在的,它被称作&the tuple splat&,并没有多少人用过它。这也是被弃用的原因之一,虽然主要还是因为这个语法会给代码带来歧义,所以才被弃用。
鉴于你可能会好奇,那我们来看一下,下面的splat语法的例子:
func describePerson(name: String, age: Int) {
print(&\(name) is \(age) years old&)
let person = (&Taylor Swift&, age: 26)
describePerson(persion)
要记住:别太喜欢你刚学的新知识,因为他们在Swift 2.2中被弃用了,并且会在未来的版本中完全移除掉
6. 更多的关键字可以用来当做参数标签了
参数标签是Swift中一个核心的特性,我们来撸一下下面这段代码:
for i in 1.stride(through: 9, by: 2) {
如果没了through和by标签,这段代码就失去了其自我注释的特性:
1.stride(9, 2)中的9和2是个啥意思?在这个例子中,Swift还使用了参数标签把1.stride(through: 9, by: 2)和1.stride(to: 9, by: 2)区分开来,这两段代码会产生不同的结果。
在Swift 2.2中,你可以用更多的语言关键字来作为参数标签了。你可能觉得为什么这会是件好事呢,考虑一下下面的代码:
func printGreeting(name: String, repeat repeatCount: Int) {
for _ in 0..& repeatCount {
print(name)
printGreeting(&Taylor&, repeat: 5)
这里用到了repeat关键字作为参数标签,这个函数会重复打印一个字符串多次。因为repeat是一个关键字,这段代码在Swift 2.2之前是会出错的,你得用别的代替repeat,这让人很不爽。
注意:仍然有一些关键字是不能用作参数标签的,特殊的如var,let以及inout。
7. var 参数被弃用
另一个被抛弃的,同样也是有原因的:var参数被弃用是因为它提供的用处微不足道,并且经常和inout搞混。这东西太不易理解了,以至于我不得不加入到我的Swift language tests,但当你读到这里的时候我可能已经删除掉了。
为了掩饰,下面是用var关键字修改后的printGreeting()函数:
func printGreeting(var name: String, repeat repeatCount: Int) {
name = name.uppercaseString
for _ in 0..& repeatCount {
print(name)
printGreeting(&Taylor&, repeat: 5)
与第一处不同的是前面的name变成了var name,并且name被换成了大写,所以会打印出&TAYLOR&五次。
没有了var关键字,name就变成了常量,uppercaseString这一行就会出错。
var和inout之间的区别非常细微:使用var关键字你可以在函数体内部修改一个参数的值,而inout会让你所做的改变在函数结束后依然有效。
在Swift 2.2中,var被弃用了,并将在Swift 3.0 中移除。如果你正在使用这个,直接在函数内给这个变量做一份拷贝就可以了,比如:
func printGreeting(name: String, repeat repeatCount: Int) {
let upperName = name.uppercaseString
for _ in 0..& repeatCount {
print(upperName)
printGreeting(&Taylor&, repeat: 5)
8.重命名了调试标识符:#line,#function,#file
Swift 2.1和更早的版本使用&screaming snake case&的符号:FILE,LINE,COLUMN和FUNCTION,这些符号出现的地方会被编译器自动替换为文件名,行号,列号和函数名称
在Swift 2.2中,这些旧的符号已经被#file,#line,#column和#function替换掉了。你会相当熟悉如果已经使用了Swift 2.0的#available来检查iOS特性。正如Swift review官方所说的,它也引入了一条出现#意味着会触发编译器的替代逻辑的规则。
下面我修改了printGreeting()函数,来看一下新旧两种调试标识符的用法:
func printGreeting(name: String, repeat repeatCount: Int) {
// old - deprecated!
print(&This is on line \(__FILE__) of \(__FUNCTION__&)
// new - shiny!
print(&This is on line \(#line) of \(#function)&)
let upperName = name.uppercaseString
for _ in 0..& repeatCount {
print(upperName)
printGreeting(&Taylor&, repeat: 5)
多亏了代码补全,我应该加上你也可以使用#dsohandle了,但是如果你知道什么是dynamic shared object handles的话,你大概已经发现了这点变化了。
9. 字符串化的selector被弃用
Swift 2.2以前一个不受欢迎的功能是selector可以被写作字符串,像这样:
navigationItem.rightBarButtonItem = UIBarButtonItem(title: &Tap!&, target: self, action: &buttonTaped&)
如果你仔细看会发现,我写的是&buttonTaped&而不是&buttonTapped&,但Xcode不会提示我出的错误,如果这个方法不存在的话。
这个问题在Swift 2.2中解决了:使用字符串作为selector被弃用了,并且你可以在上面的代码中这么写#selector(buttonTapped),如果buttonTapped方法不存在的话,你会得到一条编译错误,这又是一个需要在类编译前消除的错误。
10. 编译时Swift 版本检查
Swift 2.2 加入了一个新的编译配置项使得用不同版本Swift写的代码联合编译成一个单独文件变得简单。这看起来可能是不必要的,但是考虑到使用Swift编写库的人们,他们能把目标版本设在Swift 2.2并且期待别人都用它或者目标版本设在Swift 2.0并期待用户能用Xcode升级吗?
使用新的编译选项能让你写两种不同口味的Swift,正确的那个会依据Swift编译器的版本来进行编译。
#if swift(&=2.2)
print(&Running Swift 2.2 or later&)
print(&Running Swift 2.1 or earlier&)
就像#if os()编译选项一样,这个可以调整由编译器生成的代码:如果你正在使用Swift 2.2的编译器,第二个print()就不会被注意到。这意味着如果你愿意你可以随便胡扯点什么:
#if swift(&=2.2)
print(&Running Swift 2.2 or later&)
THIS WILL COMPILE JUST FINE IF YOU ARE
USING A SWIFT 2.2 COMPILER BECAUSE
THIS BIT IS COMPLETELY IGNORED!
11. 新的文档关键字:recommended,recommended over,和keyword
Swift支持MarkDown格式的注释来给你的代码添加额外的信息,所以你可以这么写:
Say hello to a specific person
- parameters:
- name: The name of the person to greet
- returns: Absolutely nothing
- authors:
Paul Hudson
Bilbo Baggins
- bug: This is a deeply dull funtion
func sayHello(name: String) {
print(&Hello, \(name)&)
sayHello(&Bob&)
这些信息在代码补全中会使用到(&Say hello to a specific person& 会按照你书写的方式显示)并且在快速帮助中同样有用,其他的信息这时也会显示。
在Swift 2.2中,添加了三个新的关键字recommended,recommendedover和keyword.这几个关键字通过让你来指定哪个在Xcode中匹配的属性和方法应该被返回,从而使得代码补全更有用,但是现在看起来还没作用,所以这也只是一种猜测。
当它们突然可以用的时候,我希望你是像这么使用的:
- keyword: greeting
- recommendedover: sayHelloToPaul
func sayHello(name: String) { }
Always greets the same person
- recommended: sayHello
func sayHelloToPaul() { }
正如你看到的,recommended意思是更推荐另一个方法而不是这个,而recommendedover意思是更推荐这个方法而不是别的。
正如我所说,这在当前的Xcode 7.3版本中还是不可用的,但是我提交了一个bug给Apple,期待与能得到一些明确的说明这些关键字的作用,当我知道更多的时候我也会更新这个页面。
另一方面,Xcode 7.3有了新的代码补全特性:现在你可以打出几个字像是&strapp&来得到stringByAppendingString的高亮提示。或者&uita&来获UITableViewCell高亮提示,让你的脑袋适应这种文本快捷键还需要一些重新调整,但这确实给你编写代码的速度带来了显著的提升。2.5k 人阅读
标签:至少1个,最多5个
万众瞩目的 WWDC 2017 已经落下帷幕,对于 Swift 开发者而言最关心的自然是 “What's New in Swift” 了。
在介绍 Swift 4.0 的新特性之前,还是让我们先回到 2014 年 —— Swift 横空出世的那一年吧。
2014 年的 WWDC 大会上,苹果在毫无预兆的情况下发布了用于 Mac OS X 和 iOS 编程的新一代编程语言 Swift。这一举动让很多专业的开发者一夜回到解放前,OC 程序员表示心很凉,在一门全新的编程语言面前,所有人都是零基础。所幸苹果降低了 Swift 的入门门槛,在程序编写上依然支持 Objective-C 和 C 语言,同时弥补了 Objective-C 的一些不足之处,让更多人更快地入门。
Swift 1.0 —— 横空出世
Swift 以前的 iOS 和 OS X 应用开发均使用 Objective-C,而 Objective-C 是一门及其繁琐(verbose)且学习曲线比较陡峭的语言。现在看来,Swift 1.0 确定了整个语言的基线:类型安全、迅速、现代,它告诉开发者使用 Swift 进行开发是完全可能的。Swift 1.0 有了可选的、智能的值类型,以及很多受欢迎的重大特性,得到了很多 Objective-C 程序员的认可。
从这个程序中我们可以看到,用 Swift 足够写出简洁易懂,语法上与其他脚本语言区别非常小,几乎无需学习 Swift 就能理解大概意思的程序。
Swift 是什么?简单的说:
Swift 用来写 iOS 和 OS X 程序。(估计也不会支持其它屌丝系统)
Swift 吸取了 C 和 Objective-C 的优点,且更加强大易用。
Swift 可以使用现有的 Cocoa 和 Cocoa Touch 框架。
Swift 兼具编译语言的高性能(Performance)和脚本语言的交互性(Interactive)。
仅在 Swift 发布的 11 个小时后,开发者 Nate Murray 就放出了基于测试版 Swift 开发的应用 —— 一个重制 Flappy Bird 的简易原型。
推荐对 Swift 感兴趣的开发人阅读这个新作品的代码,并同时建议下载一份目前的版本试用或收藏。
动作快的小伙伴也第一时间上手用起来,嗯,用过都说好。
手把手教你如何完成一个 TODO 的应用,功能很简单,就是添加任务和浏览任务。将视屏内容整理了一下。虽然没有什么高深的内容,但是作为一个入门的小程序还是挺适合的。
上一次微软大张旗鼓的推出 C# 及其编程平台还是在 2000 年,而将近15年之后,苹果推出了另一门编程语言 Swift。作为一个开发者,能见证一门编程语言的诞生,备感荣幸。
Swift 2.0 —— 开源万岁
在 2015 的 WWDC 大会上,苹果宣布将开源 Swift。此外苹果还将公开发布在 OSI 标准许可下的 Swift 的源代码,包括编译器和标准库,开放 Linux 的源代码端口,开发者可以在 Linux 上编写 Swift 程序。不难看出,苹果这些举动意在鼓励开发者从而进一步推动 Swift 的发展。
经过一年的发展,Swift 2.0 有了哪些新特性呢?
Swift 2.0 涵盖了更多新的功能,如升级的错误处理、协议扩展和可用性检查等。
今年 6 月,一年一度的 WWDC 大会如期而至,在大会上 Apple 发布了 Swift 2.0,引入了很多新的特性,以帮助开发者能更快,更简单的构建应用。
作为这门语言的使用者,必然也会受到它的影响。
每一门编程语言都会有一个从推出到趋之完善的过程。Swift 和 Xcode 的问题虽然饱受诟病,然而,个人相信,随着时间的推移和语言自身的成长,Swift 的将来必定会成为主流开发语言之一。
Swift 横空出世,如火如荼,那 Swift 在未来有可能会取代 Objective-C 吗?
当然。但是没人知道会用多长时间,但是我认为应该是在 5 年之内。我们很容易就忘记计算机语言的生命有多长(现在 C 语言已经 40 岁了)。Objective-C 不会彻底消失,但是我能预见在未来的某一个时刻,它在语言世界中的份额将变得非常小。
那么问题来了,如何以最短的时间快速从 Object-C 过渡到 Swift?
那就是查看 API 文档,这是一个极其取巧且快速省心掌握 OC 和 SW 之间语法变化的方法
Swift 3.0 —— 打破一切
2016 年 9 月,苹果发布了被称为 “破坏性更新” 的 Swift 3.0。Swift 3.0 可谓 “打破一切”,如果你已精通 Swift 2.0,那升级到 Swift 3.0 无疑是从精通到入门。
保证语言基础的健全以及一致性是一门新语言发展的必经之路,因此也将受到挫折。Swift 3.0 可能不是最有趣的版本,但它让 Swift 更为干净。
这意味着什么?恩,首先,从 Swift 2 过渡到 Swift 3 不可避免地将是悬崖式的过渡,大量的代码需要重写,Cocoa 的重命名工作也要落地了,我们将再次创建令人瞩目的科技成果。同样地,我们应该尝试将 “重新布局式的” 改变放到 Swift 3 中,如果可能的话,Swift 3 到 Swift 4 的过渡尽可能平缓一些。
还是按照惯例,继续来看看 Swift 3.0 的新特性吧:
经历了从 Swift 1.0 到 2.0,一个版本之后代码居然就不兼容了。这如何在团队推广呢?没有想到 3.0 居然变化更加的大。有多大,来体会一下。
如果你没有一直紧跟 Swift Evolution 的话,你也许会想知道都有哪些改变,以及它将会怎么影响你的代码,并且你该什么时候开始着手把代码 convert 到 3.0,那这篇文章就是写给你的。
嗯,看到这里,Swift 2.0 的开发者的内心是崩溃的,含泪写下从 Swift 2.2 到Swift 3 的迁移指南。
Xcode 8 带着 Swift 3 风风火火的到来了,作为一个平时使用 OC 为主的 iOS 开发来说,Swift 3 正式和 OC-like 语法划定了界限。
Swift 4.0 —— 充满希望
在开始 Swift 4.0 之前,还是先来看看开发者们对它的期望吧。
Swift 3 的正式版已经接近完成状态了, 是时候来回顾一下发布之前的事情, 从中汲取经验, 并且用来整理一下我们(Swift 社区)在今年做的事情了. 总的来说, Swift 3 无疑将会是一个 Amazing 的版本, 我们做到的很了不起, 谢谢每一个为这件事情贡献力量的人. 比起马上推进那一堆新计划, 更重要的是让我们每个人从整个大局来看, 了解自己做到的这些了不起的事情.
需要补充的一点是,自从 Swift 开源之后,大部分社区成员提交的提案都在讨论和修改之后被接受了。而那些被驳回的提案也都在激烈的讨论之后由核心团队来做最后的决定。就连 Apple 自己的工程师在想要做出改变的时候也会打开 Repo 去写提案。借助开源,苹果充当管理者的角色,确保了语言的一致性,通过开源社区的力量更好的完善语言的功能,让 Swift 成为一个更好的语言。
说回本次的更新。
new encoding and decoding, smarter keypaths, multi-line strings, and more!
从 WWDC 2017 发布的情况来看,Swift 4.0 做了很多重大的改变,包括 String 的重新设计,Codable 协议的原生支持,原生的 JSON 解析,以及其它很多功能的改进等。因此 Swift 4.0 与 Swift 3.0 并没有十分良好的代码兼容性。
然而,Swift 推出伊始,它的编译器就是支持兼容性模式的,选择 -swift-version-3 能编译大多数 Swift 3.0 的源码,此外在 Swift 4.0 中还修复了错误代码也能在旧编译器中编译通过的漏洞。而 -swift-version-4 将支持所有在 Swift 4.0 设计准则中提到的新特性,开发者可以以 package 为单位逐步将自己的代码库迁移过来。
Swift 4.0 将在 2017 年秋季发布。“种一棵树最好的时间是十年前,其次是现在”,如果你也想尝试用 Swift 进行 iOS 开发,那么现在就动手吧!
Swift 2.2 版本:
Swift 3.0 版本:
“Write the Code, Change the World”,开发者们,让我们拥抱变化,用代码来改变世界吧!
(本期完)
# SegmentFault 技术周刊 #
「技术周刊」是社区特别推出的技术内容系列,一周一主题。周刊筛选的每篇内容,是作者的独到见解,踩坑总结和经验分享。
每周四更新,欢迎「」或者「」。大家也可以在评论处留言自己感兴趣的主题,推荐主题相关的优秀文章。
4 收藏&&|&&44
你可能感兴趣的文章
45 收藏,3.3k
134 收藏,2k
179 收藏,5k
275 收藏,3.2k
350 收藏,4.5k
449 收藏,4.2k
Swift 从入门到重新入门 -- 四(次), 还是写 OC 好
Swift 从入门到重新入门 -- 四(次), 还是写 OC 好
同事去年底刚用2.2写的Swift应用就要发布,现在看到稳定版的3都想哭了,然后4又要来了……
整理的很好??
同事去年底刚用2.2写的Swift应用就要发布,现在看到稳定版的3都想哭了,然后4又要来了……
整理的很好??
技术发展太快,作为开发者也只能努力跟上它的步伐。能用4就尽量用4吧,以后优秀的开源库肯定都是居于4的。加油吧,少年!????
技术发展太快,作为开发者也只能努力跟上它的步伐。能用4就尽量用4吧,以后优秀的开源库肯定都是居于4的。加油吧,少年!????
Swift 版本更迭太快,步子迈得的确有点大,本期已自动忽略 Swift 2.2,2.3,3.1等,欢迎小伙伴们在评论区吐槽 ^ ^
Swift 版本更迭太快,步子迈得的确有点大,本期已自动忽略 Swift 2.2,2.3,3.1等,欢迎小伙伴们在评论区吐槽 ^ ^
@keke ????
@keke ????
分享到微博?
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。充满争议的领克01,网友们对它的态度如何?
(0人已关注)
浏览数:加载中...
9月28日我来到宁波,测试了一台可能成为自主品牌里程碑式进步的车型,吉利全新豪华子品牌领克的第一款车——领克 01。但由于保密协议的原因,直到10月10号我才能开口讲讲这辆车的好与不好。&接下来的两天时间,领克01的各项数据出来了,而我也把我的驾驶感受发到了微博上,这款特别的车型也引起了网友们的热烈讨论…&领克01的各项数据是多少?数据我在周二的文章里讲过了,沃尔沃CMA平台,来自沃尔沃的Drive-E系列2.0T(未来会有1.5T)发动机拥有190马力和300牛米的峰值扭矩,匹配7DCT湿式双离合变速箱(四驱)和爱信6AT变速箱(两驱),百公里加速均小于8秒。&&网友对这辆车的评价是什么? &澄清一下,领克01采用的四驱系统是翰德5代&有说丑的,主要是“嘴”和“灯”之间没有一个主体,看起来不协调VV7的造型明显更虎一些,比较讨喜,相反领克01是走精致路线的我也关心多少钱!&开01在赛道上跑一跑除了普通试驾,我还开着01在赛道上转了转 &四款车型四种设计风格,你喜欢谁?领克01此次提供了四款车型,分别为耀、型、劲、纯,分别体现了个性前卫、内涵优雅、运动极限和简单纯粹四种风格。网友们更喜欢哪种风格?我们做了个统计。&耀和劲以高票数胜出,看来更加个性的设计更讨网友们喜欢,也侧面反映出了领克目标人群的年轻。&最后,对于领克01这款车,你们喜欢么?会买账么?对了,领克的首款轿车03要参加WTCC了&&轮到你说:对于领克01这款车,你们喜欢么?会买账么?
内容仅代表作者观点,与易车网无关
日前,“源于初心 笃信力行”马自达“Zoom-Zoom可持续发展战略2030”说明会在北京举行。会上,马自达就企业未来技术开发长期愿景进…
10万预算想买SUV,啥车型值得考虑?
看了这款2.5T的新阿特兹,你还会买雅阁买凯美瑞吗?
在电动车占领世界前,我只想拥有一辆V12
如果当年日产推出这台车,也就没有本田NSX什么事了
请输入正确的帐号和密码
用户已经被禁止
活动推荐广告
收藏成功!&&
您举报的类型是?
感谢您的举报
我们会尽快审核处理
已经举报过啦《好看》依托百度技术,精准推荐优质短视频内容,懂你所好,量身打造最适合你的短视频客户端!充满争议的Swift协议:该如何正确使用?
发表于 17:00|
来源owensd.io|
作者David Owens II
摘要:国外对于Swift中协议的使用有很多争议,有人认为应尽量多用,而有人则觉得应该限制使用。本文作者就代码中使用协议时需要注意的规则提出了自己的看法,即不要把协议当成类型;不要把协议泛型化,除非你必须这么做!
CSDN移动将持续为您优选移动开发的精华内容,共同探讨移动开发的技术热点话题,涵盖移动应用、开发工具、移动游戏及引擎、智能硬件、物联网等方方面面。如果您想投稿、参与内容翻译工作,或寻求近匠报道,请发送邮件至tangxy#csdn.net(请把#改成@)。&本文出自:,译文出自:最近Swift的热点都围绕在协议上,他们觉得任何东西都应该是协议。理论上这挺好,但是事实上,这种观点会产生一些副作用。我在代码中使用协议时,总是牢记下面两条规则:1. 不要把协议当成类型我看到的(和我一开始写的)许多方法都是在继承关系里把协议当成一个基类。我不认为这是协议的正确用法,这种设计模式仍然停留在“面向对象”的思维方式上。换句话说,假如你的协议只在继承关系里有意义,那就应该扪心自问是否真的有必要使用协议。我不赞同这种说法:“我的类型是结构体,所以我需要用协议来代替。”如果真的需要这样,那就重构它,把它变得更通用。进一步的验证可见:。需要关注所有那些协议(不以 _ 开头的协议)吗?所有的协议都能适用不同的类型,不管是不是类型继承。2. 不要把协议泛型化,除非你必须这么做!这并不是一个小问题,一旦你把协议泛型化,就无法再使用包含不同协议实例的类型集合。我认为这是严重的设计缺陷。比如说,无论在哪里使用协议,协议中所有不受Self限制的功能都应该保证调用安全。这条规则同样适用于遵守泛型协议的协议,比如Equatable,泛型会传染。下面这行代码就是典型的例子:protocol Foo : Equatable {}来个实际点的例子吧:我们想要对HTTP response建模,并且想要支持两种不同的response类型:String和JSON。你可能会这样写:class HTTPResponse&ResponseType& {
var response: ResponseType
init(response: ResponseType) { self.response = response }
}我认为这样写不好。一旦这样写,我们就人为地限制了使用这个类型的能力;比如,这不能在复杂情况下的集合里使用。现在,为什么我想要在集合里使用不同的ResponseType?假设,我想要构建一个 response/request的测试工具。返回response的集合里需要有我支持的类型:String和JSON。使用AnyObject是个不错的做法。虽然可行,但是真的很操蛋。另一种方法是使用协议。然而,除了构建ResponseType协议之外,让我们想想真正想要什么。我真正关心的是,HTTPResponse接收到的ResponseType都能表示成String。揣着这样的想法,我写出这样的代码:protocol StringRepresentable {
var stringRepresentation: String { get }
class HTTPResponse {
var response: StringRepresentable
init(response: StringRepresentable) { self.response = response }
}对我而言,这为API使用者提供了极大的方便,也维持了类型的明确性。当然,这样做是有弊端的。假如你真的需要为response使用特定的类型,那么就需要进行类型转换。class JSONResponse : StringRepresentable {
var stringRepresentation: String = "{}"
let http = HTTPResponse(response: JSONResponse())
let json = http.response as? JSONResponse这个方法明显更好。调用者知道可能的返回类型或返回值。这明显与遍历整个集合取出返回值是不同的,因为,代码的使用者可能使用的是其他的返回类型,比如 XMLResponse ,而我们的代码不可能知道这个。最好是这样写:class HTTPResponse&ResponseType : StringRepresentable& {
var response: ResponseType
&span style="font-family: Helvetica, Tahoma, Arial, sans- font-size: 14 white-space: background-color:"&let responses = [json, string] &//responses变量是以HTTPResponse为元素的数组,元素中的ResponseType是未指定的。&/span&如果要用集合,你还是需要强制转换response的类型,不过现在你可以直接用JSON实例来验证类型。反正我是每次都用[HTTPResponse]类型的集合,而不是[AnyObject]。预告:将于10月15-16日在北京新云南皇冠假日酒店召开。大会特设五大技术专场:平台与技术iOS、平台与技术Android、产品与设计、游戏开发、企业移动化。此外,大会更是首次举办国内极具权威影响力的IoT技术峰会,特设硬件开发技术与虚拟现实两大专场。大会将聚集国内最具实力的产品技术团队,与开发者一道进行最前沿的探讨与交流。第一时间掌握最新移动开发相关信息和技术,请关注mobilehub公众微信号(ID: mobilehub)。
推荐阅读相关主题:
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章

我要回帖

更多关于 协议争议解决方式 的文章

 

随机推荐