Swift 中的安全性

作者:Soroush Khanlou,原文链接,原文日期:2017-04-05
译者:Doye;校对:walkingway;定稿:CMB

Swift 是一门注重安全性的语言,如Swift官网关于页面中所言

Swift 是一门通用编程语言,采用现代化的方法来保证安全性与性能,套用软件设计模式。

还有它的说明

  • 安全性:那些显而易见而又便捷的编程方法应该保证是安全的。未定义的行为会破坏软件的安全性。在软件发布之前就要把开发者的错误扼杀在萌芽之中。强调安全性有时会让你觉得 Swift 语法过于严苛,但是它带来的代码的明晰从长远来看还是利大于弊的。

  • 高性能: Swift旨在替代 C 系语言(C,C ++和Objective-C),因此 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:

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

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

推荐阅读更多精彩内容