做者:Soroush Khanlou,原文连接,原文日期:2017-04-05
译者:Doye;校对:walkingway;定稿:CMBhtml
Swift 是一门注重安全性的语言,如Swift官网的关于页面中所言git
Swift 是一门通用编程语言,采用现代化的方法来保证安全性与性能,套用软件设计模式。程序员
还有它的说明github
安全性:那些显而易见而又便捷的编程方法应该保证是安全的。未定义的行为会破坏软件的安全性。在软件发布以前就要把开发者的错误扼杀在萌芽之中。强调安全性有时会让你以为 Swift 语法过于严苛,可是它带来的代码的明晰从长远来看仍是利大于弊的。编程
高性能: Swift旨在替代 C 系语言(C,C ++和Objective-C),所以 Swift 必须在绝大多数任务中与这些语言有着接近的性能指数,并且性能须要具备可预测性。并且这种指数须要是一种广泛的性能指数,而不是昙花一现的仅仅几种任务类型的高性能。具备各类特性的语言有不少,但仍保持着如此高性能却实属罕见。swift
表现力: Swift 受益于计算机科学的几十年发展,提供了开发人员指望的现代功能并具备有趣的语法。并且 Swift 并不止步于此,Swift 社群会关注编程语言的发展并取其精华,使得 Swift 一直保持进化,变得更好。设计模式
举例来讲,相似 Optional 这种类型就是 Swift 考虑安全性的一个体现,在其余的编程语言当中,你并不能知道哪一个变量能够为空(null)哪一个不能,而 Optional 携带着改变量可能为空的信息,这就强制开发者去考虑可能为空的状况。对于”可空”(nullable)的类型,若是你用强解包符号(!)来处理该类型,有些时候它会直接 crash。Swift 的安全性至关于一条安全带,你能够自行解开它,可是风险也要本身来承担。数组
然而在某些状况下,安全性看起来并不足够。好比举例来讲,若是咱们有一个字典,咱们须要经过一些 key 来提取到返回值类型为 optional 的 value安全
let person: [String: String] = //... type(of: person["name"]) // => Optional<String>
可是若是咱们对数组进行相似的操做,咱们并不会获得一个 optional:app
let users: [User] = //... type(of: users[0]) // => User
缘由是数组可能没有元素,若是 users 的数组为空的话,这段程序将会直接crash,从这方面来看,好像Swift并无作到足够安全。
Swift仍然在开放的演进中,你可能就此问题提些建议到 Swift evolution邮件组
不,那也不会有什么改变,在 Swift evolution 的 github 库里 ”常见驳回”提议页 当中描述了不会接受这项提议:
Array< T > 的下标获取操做不返回一个 T 而是返回一个 T? 或者 T!,当前的数组的逻辑是故意为之,它准确反映了访问越界的数组下标是一个逻辑错误。若是改变目前的逻辑会下降数组的读取到一个没法接受的程度,这项提议提出屡次并不会被社区采纳。
这里指出的缘由是在这种特殊状况下,性能相当重要。可是若是咱们回过头来看上面引用的关于页当中的信息,”安全性”的地位应该是高于”速度”的,难道安全性不该该比速度更为重要么?
这里存在着一个根本的争议点,在于”安全性”一词的定义。对于”安全性”一个广泛的理解是不 crash,而 Swift 核心成员的定义是”永远不会在无心中访问错误的内存”。
从这点来看,Swift 的下标操做是”安全的”,它永远都不会去访问在数组自身分配以外的内存,当你想访问数组越界的内存时它会当即 crash,如 Optional 类型避免了当前存在的各类空指针引用的 bug 同样,数组这里的考虑避免了缓冲区溢出的 bug。
Chris Lattner(Swift 做者)在这段采访的24.39处有段说明
咱们采用的安全性策略是在综合的一种妥协。咱们想使Swift成为一门安全的编程语言,但这种安全并非没有bug,而是咱们保障内存安全的的基础上同时提供高性能并且采用一直前进的编程语言范式。
或许,内存安全相对于安全是一个更好的名词,有些开发者可能更偏向于获得一个 optional 的返回值,而不是在数组越界访问的问题里纠结,每一个人都赞成直接让程序crash会好过让程序携带着非法的数据继续运行下去,而这种状况还可能会被栈溢出的攻击所利用。
第二种权衡(直接 crash 而不是容许越界访问)的决定看起来显而易见,可是有些语言不会作这种保证,在 C 中,访问越界的数组将会致使未知的行为(具体取决于使用的编译器对这种行为的实现),在 Swift 中开发者会快速的意识到本身犯了相似数组越界的错误,Swift团队以为这是一个合适的 crash 时机,因此并不会返回一个 optional 甚至是返回一段未知的数据。
使用这里”安全”的定义也明确了”不安全”的 API 的定义,由于它们直接访问内存进行编程,程序员们本身必须十分当心保证本身不会访问到无效的内存,这点尤其困难,即便专家在这种情景也会犯错,若是对这个主题感兴趣去查阅 Matt Gallagher的博客中以安全的方式桥接 C 到 Swift 的相关讨论。
Swift 的团队对于安全的定义可能与你预想的并不彻底一致,可是它们的种种策略确实能够避免大多数的程序员去考虑各类常见的 bug,将“安全”的定义细化为“内存安全”可让我更好的理解 Swift 团队对于安全的定义。
本文由 SwiftGG 翻译组翻译,已经得到做者翻译受权,最新文章请访问 http://swift.gg。