WWDC2016 Session 402 - What’s New in Swift

Swift 开源已有6个月,开源社区讨论从未停歇过。Swift3 的目标有以下4点:

  1. 发展开源社区
  2. 新平台的可移植性(目前面向macOS和Ubuntu)
  3. 开放更多基础功能
  4. 持续优化

前往Swift.org 了解更多。

Swift 在 Apple 中的普及率

目前公布的 Sierra macOS 系统中,大部分 Misson Control 都已经使用 Swift 重写,甚至 Accessibility 引擎完全使用了 Swift。

Ted Kremenek 以 Dock 为例,讲述关于这个20万行代码的应用使用 Swift 重写后代码量减少了15%之多,同时又增加了一些新功能。

GitHub 上的 Swift

众所周知,Apple 开源了 Swift,将项目托管到了 GitHub,项目有很多,譬如:swift、swift-evolution、swift-package-manager、swift-clang、swift-corelibs-libdispatch等等。不过实际可以划分为三类:

  • Language:swift swift-evolution
  • Package Manager:swift-package-manager swift-llbuild
  • Core Libraries:swift-corelibs-xctest swift-corelibs-foundation swift-corelibs-libdispatch

更多请前往 GitHub 了解更多

如果你想要对 swift 提出自己的想法或意见,这意味着 evolution,Apple 十分欢迎开发者踊跃参与,但是貌似国内很多小伙伴不是很了解。大致流程是:

  • 邮件交流,讲述你的想法,如何改动。
  • 以 pr 方式提交你的建议。
  • 一旦接受,开始review。
  • 邮件列表中review,比较正式。
  • 开发团队决断,打回or接受。

这里提供提案的列表,目前有102个,有兴趣可以看看,实时关注swift的动态。

关于 swift 的改动

Swift 3 的核心任务或者说是目标是提高兼容性,这对于跨平台开发至关重要。不仅是针对 Swift3,亦包括 Swift4.0 版本。

下面根据视频简单罗列一些:

命名准则

API 设计准则中重要几点:

  • 一目了然,而非过分简洁或冗余。
  • 突出重要信息
  • 省略冗余信息

更多请见Api-design-guidelines,貌似 Swift.gg 已经有中文版了哦。

举例:

swift 2

/// Swift.Array
array.appendContentsOf([2,3,4])
array.insert(1, atIndex: 0)

/// Foundation.NSURL
if url.fileURL {}
x = url.URLByAppendingPathComponent("file.txt")

swift3

/// Swift.Array
array.append(contentsOf: [2,3,4]) // 作为标签存在更加清晰
array.insert(1, at: 0) // index 没有存在的意义

/// Foundation.NSURL
if url.isFileURL {} // 这里平常都会用到吧
x = url.appendingPathComponent("file.txt")// 都已经是URL 何必加 URLBy前缀呢

很明显改进后调用意图不变,但是精简了很多。

Objective-C API 和 Swift 桥接问题

这里推荐 swift.gg 的SE-0005 更好的把 Objective-C APIs 转换成 Swift 版本

简单举例:

swift2

// oc
void CGContextFillPath(CGContextRef);//这是Core Graphic 画图库中的函数!不是方法
// import 调用API变成如下 还是一个函数
func CGContextFillPath(_: CGContext)

swift3

// oc
void CGContextFillPath(CGContextRef)
           NS_SWIFT_NAME(CGContext.fillPath(self:));// 注意NS_SWIFT_NAME修饰符
// 对 CGContext 扩展
extension CGContext {
  func fillPath()
}

在说说泛型:

swift2

func findAnimals() {
  let request = NSFetchRequest(entityName:”Animal")
  guard let searchResults =
           try? context.executeFetchRequest(request) as! [Animal] {
    return
  }
  ...
  use(searchResults)
}

swift3

func findAnimals() {
  let request : NSFetchRequest<Animal> = Animal.fetchRequest 
  guard let searchResults = try? context.fetch(request) {
    return
  }
  ...
  use(searchResults)
}

旨在实例化一个对名为 Animalentity 请求,以前的写法是构造函数,而新的是上述这种方式,已惊呆。

// oc 
typedef NSString *NSNotificationName; // 对 NSString 设置别名
const NSNotificationName NSUserDefaultsDidChangeNotification; // 变量A

// swift 导入
let NSUserDefaultsDidChangeNotification: String // oc变量A在swift中 实际就是String类型嘛

// 使用
center.addObserver(forName: NSUserDefaultsDidChangeNotification, ...) // 冗长

swift3

typedef NSString *NSNotificationName NS_EXTENSIBLE_STRING_ENUM; // 注意修饰词 变成了一个枚举值.....
const NSNotificationName NSUserDefaultsDidChangeNotification;

// swift 导入
extension UserDefaults {
  class let didChangeNotification: NSNotification.Name
}

// 使用1
center.addObserver(forName: UserDefaults.didChangeNotification, ...)
// 使用2
center.addObserver(forName: .didChangeNotification, ...)

核心语言

函数参数标签的一致性

swift2

func myFunction(a: Int, b: Int, c: Int) { } 
myFunction(42, b: 57, c: 99)// 没有 a 标签名

swift3

func myFunction(a: Int, b: Int, c: Int) { } 
myFunction(a: 42, b: 57, c: 99)

这个改动应该很早就提及过。如果你不是很愿意显示参数标签,用 _ 忽略吧。

不知道大家对 where 这个条件语句用的多不多,swift3 也做出了些许改动,主要是在放置位置上。

swift2

func anyCommon<T: Sequence, U: Sequence
               where T.Element: Equatable,
                     T.Element == U.Element
               >(lhs: T, rhs: U) -> Bool {}

注意我们的函数名和参数列表之间掺杂了太多语句了!

swift3

func anyCommon<T: Sequence, U: Sequence>(lhs: T, rhs: U) -> Bool 
          where T.Element: Equatable, T.Element == U.Element {}

在我们写完函数定义之后再写限制条件 where。很nice!

再来看看对未使用变量的处理

swift2

func plusOne(_ a: Int) -> Int {
  return a+1
}
plusOne(x)// 发出⚠️警告,因为这个函数是有返回值

swift3

@discardableResult
func plusOne(_ a: Int) -> Int {
  print(a)     // side effect!
  return a+1
}
plusOne(x)
_ = plusOne(x)

注意@discardableResult 修饰符。

Swift3 移除的特性

移除东西可能让你惶恐不安,但是这也是苹果深思熟虑,权衡众多开发者提出的意见之后做出的决定。目的有三:

  • 致力于简化语言
  • 减少代码上手难度
  • 向其他语言学习,取其精华,去其糟粕

目前有哪些移除了的呢?

  • SE-0002 Currying func declaration syntax
  • SE-0003 函数参数列表中的 var
  • SE-0004 ++ 和 -- 运算符
  • SE-0007 C 语言中的 for 循环

又有哪些新加入的呢?

  • SE-0025 加入 fileprivate 作用域范围,咱们用的比较多的是 public private
  • SE-0043 case 标签的值绑定操作
  • SE-0048 泛型别名,貌似是associatedType

其他还有 SE-0062 SE-0064 SE-0068 SE-0075 SE-0092,不妨去 GitHub 上一睹为快吧。

修改又有哪些呢?

  • SE-0028 #file 替换了 FILE
  • SE-0031 inout 变成了类型的一部分
  • SE-0040 属性语法: :替换=
  • SE-0049 @noescape@autoclosure 可以类型属性
  • SE-0060 dynamicType 不再是属性 而是运算符。

类型系统的改变

先看一则 swift2 的例子:

let ptr : UnsafeMutablePointer<Int> = nil
if ptr != nil {
   ptr.memory = 42
}

而在swift3 中则是这样干

let ptr : UnsafeMutablePointer<Int>? = nil 
ptr?.memory = 42

Imported C pointers in APIs obey _Nullable and _Null_unspecified
Consistency: nil is dedicated to Optional and ImplicitlyUnwrappedOptional

隐式解包可选类型(IUO Implicitly Unwrapped OptionaL)

swift2 中类型系统是这么推断的:

func f(value : Int!) {
  let x = value + 1  // x: Int - 强制解包的结果
  let y = value      // y: Int!
  let array = [value, 42] // [Int], [Int!], [Int?], [Any]... 它无法推断类型了 因为它不知道y到底是有值呢还是nil呢
   use(array) //Cannot convert value of type ‘[Int!]’ to argument type
}

swift3 中类型系统就聪明很多了:

func f(value : Int!) {
  let x = value + 1  // x: Int - 强制解包的结果
  let y = value      // y: Int?
  let array = [value, 42] // [Int?], 
   use(array) 
}

浮点数和数字

直接上代码:

/// swift2
let v = 2 * Float(M_PI)
return x * CGFloat(M_PI) / 180

/// swift3
let v = 2 * Float.pi
return x * CGFloat.pi / 180
return x * .pi / 180      // amazing!

更多

之后是关于 Swift Tools 的简单介绍,基本就是说提升了多少性能,提供了swift2.2->swift2.3 swift2.2->swift2.3的转换方式,可以选择编译优化,速度更快,以及提示更加智能。这里不一一称述。基本来看这个视频只不过是概括性地讲了下改动,没有具体讲到某个细节。所以喽,只能作为开胃菜吃着先,更多请见专题。

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

推荐阅读更多精彩内容