在分析之前,我先把我的观点表明 :"Swift
是未来"。在本文中,我将慢慢揭开Swift的神秘面纱。我会介绍一些Swift 2.0的关键点,比如LLVM
的优化,Generics Specialization
(泛型特化),Value Syntax
(Value 语法)和Protocol Oriented Programming
(面向协议编程).
本文目录
- 一切取决于编译器
-
LLVM
和Chris Lattne
- 泛型
-
Value
语法 - 面向协议
- 总结
一切取决于编译器
前言
在古老的二进制世界中,C
语言比任何语言跑的都要快,这是一个事实,而且这个状态仍然存在。然而……,Swift
却在运行时跑的更快,为什么?
并不是单纯的比C
语言运行快,而是比在我们日常工作中任何一个纯C
语言编写的程序都快。虽然用大量的C语言代码和高度优化的超级程序可以和swift
的速度比肩,但是这个程序将是一个庞然大物,它需要一个庞大的团队协力开发,这基本上是很难去管理的一个项目。
这点就是我们所有人共同的想法:“嗯,我们需要创造一个低级代码进行高度集成优化的编译器或者框架,让普通开发人员编写相同的丰富的代码,并且让所有的开发人员在实现软件高性能的同时更多的去交流和创造艺术等高级状态,同时让大型的开发者团队保持代码的可读性”。这就是swift
的编译器背后基本想法。
这就是编译器……是的。我们都知道,LLVM
编译将C
和objective - C
的代码放到一个低级容器中,然后编译成机器代码。在Swift
中LLVM
做着同样的事情,编译成汇编代码在整个编译阶段。在这一点上变成真正有趣的东西。
现在用编译器可以很容易的编写成以前需要用C来写起来比较困难的优秀代码。LLVM
做很多事情可以基于Swift
代码,如在一个普通的项目将大量重建相同的代码。但请记住,这是一个Swift2.0
的新特性。这种力量让我们看到更多swift2.0
的新功能。
LLVM
和Chris Lattne
前言
自他还是个大学生时 Chris Lattner
便是顶尖的编译器工程师。2005进入苹果公司从事LLVM
编译器的工作,在2011年苹果公司给了他一个很好的机会:创建一个新的高级语言,可以让他所有的天才想法作用于LLVM
。Lattner
与其他几个开发者开始编写swift
语言。
Lattner
感受到苹果公司伟大目标和责任的重大。他对应非常快,带着LLVM
和Clang
向更高水平发展,他创造了C
语言Blocks
功能,一块超级优化的代码,在运行时可以运行非常快,由于其对待栈内存。如果你记得iOS 4 ,那就知道Blocks
是使GCD
变成了可能。
Lattner还为objective - c
创建ARC特性方面做出了贡献。正如你所看到的,他是负责了最后5年苹果开发最先进的特性。Swift
,Lattner的最大的梦想。但是却有一个奇怪的事情:在开发swift
的时候,他都是晚上在家里完成的。在秘密开发swift
的一年半的时间里,他没有告诉苹果公司里任何人,甚至他最亲密的朋友。仅仅在2011年Chris
在苹果高管会议上透露他的秘密。
苹果指定了很少一些开发者从事swift
项目工作,一年半后,swift
项目成为苹果最大的焦点。你能想象什么是Lattner的梦想吗? “创造一个语言,并迅速的改变计算机世界”,《Wired》杂志的这样写道。
正如C的创造者(Dennis Ritchie
和Kenneth Thompson
)改变了计算机世界一次,Chris Lattner
再次这样做,这次使用编译器的力量!
现在苹果在这一部分…我怀疑这样说,因为我真的很喜欢苹果,但让我们看看如何苹果的营销是伟大的。谷歌GO
语言第一次出现在2009年,6年后,它甚至没有出现在前50名在Tiobe
排名中。Swift是1岁,这是达到前十名Tiobe(虽然objective - c
是自由落体跌到了第5名)。Tiobe链接
嗯,当然GO
和Swift
之间有很大的区别,GO
也达到更高的Tiobe排名在刚推出的时候,但是come on…Go
是由C
语言的创造者之一创造的并且Google
的站在了它的背后,一个成功的组合,但是看起来效果并不好。我敢说,现在swift
是更有可能改变计算机世界的对比任何其他语言。
现在,swift
是开源的,正如去年Mike Ash
希望的那样。
泛型
前言
我最喜欢的东西之一,Swift
是泛型的!然而,对于运行时泛型是一个定时炸弹。
为了运行可靠的代码,编译器应该增加更多的检查和双重检查使用一个通用的指令。但是在swift 2.0
并没有更多的了。再一次,“编译器的力量!“LLVM
现在可以处理更多的事情在我们的代码,不只是检查一个文件,而是检查整个项目。通过这样,编译器可以创建特定版本的泛型,这称为泛型特化。
// 思考一个泛型函数
func maxFunc(x: T, _ y: T) -> T {
if x < y {
return y
}
return x
}
...
// 另一个文件
var a = 4
var b:Int = 2 + 3
var c = maxFunc(a, b)
现在swift 2.0
编译器可以推断,上面的代码可以取而代之的是:
// 通过泛型专业化生成的版本
func maxFunc (x: Int, _ y: Int) -> Int {
if x < y {
return y
}
return x
}
通过这个优化版本,编译器在运行时能保证更高的性能。
这和多年前的isEqual:
和isEqualToString:
是相同的概念。都做同样的工作,您可以使用两个NSString
实例,但是第二个可以运行得更快,因为它可以避免不必要类型检查。
Value 语法
前言
这一特性在Swift 1.x
版本中就已经存在。但现在它比以前更优秀了。Value
语法刚好和引用语法(Reference Syntax
)相反,它是一个用于C指针和consequentely
objective - C
的类。C语言的struct
和C的基本数据类型使用Value
语法,所以这里没有最新进展。
只是要记住,这里有两种语法的一个例子:(objective - c
)
// Value 语法, 内存复制.
CGRect rect = {0.0, 0.0, 100.0, 100.0};
CGRect rectVS = rect;
rect.size.width = 50;
rectVS.origin.x = 10;
NSLog(@"%@", NSStringFromCGRect(rect)); // Prints {{0, 0}, {50, 100}}
NSLog(@"%@", NSStringFromCGRect(rectVS)); // Prints {{10, 0}, {100, 100}}
//这里表达的意思是在赋值的同时,把rect的值是在内存重新复制了1 份,这是一个新的内存地址,
而不是引用的原来rect的内存地址
// 引用语法,内存共享
CGRect *rectRS = &rect
rect.size.width = 25;
(*rectRS).origin.x = 10;
NSLog(@"%@", NSStringFromCGRect(rect)); // Prints {{10, 0}, {25, 100}}
NSLog(@"%@", NSStringFromCGRect(*rectRS)); // Prints {{10, 0}, {25, 100}}
//在这里 rectRS 直接饮引用了rect的内存地址,所以在内存中并没有开辟新的内存空间,
所以这两个指针都指向了同一块内存地址,所以修改的时候不管是修改那个指针的值,
都是修改的同一块内存空间,所以最后是width和x同时改变了
正如你所看到的,都有它的用途和价值。objective - C
的事情是,你必须知道C
指针和C
的数据类型 为了正确处理Value
和Reference
(引用)语法。Swift 2.0
中的新特性再次具备了推断事物的能力,所以…“编译器的力量!”
LLVM
可以推断出更多基于代码和项目文件。它能够确定一个变量/常数必须使用value
语法或引用语法。Swift
是默认值基于Value
语法的,但是您可以使用这两种方式如果你想要通过改变代码的架构(如创建封装类)或通过强制(使用inout
指令)的引用。inout
(地址引用),你猜怎么着……它的语法和在C语言中是一样的,用“&”。太棒了!
func fooSum(inout varA:Int, varB:Int)
{
varA += varB
}
var a = 5
let b = 3
fooSum(&a, varB: b)
print(a)
面向协议
前言
这是我想谈谈的最后一部分,但我认为这是Swift 2.0
最令人兴奋的事情。你猜怎么着,这又是编译器的事:“编译器的力量!”,但这一次,它是如此巨大,这是一个完全改变范式和真的可以改变我们的方式。
Swift
2.0现在被称为面向协议的编程,相对于面向对象编程。那是为什么?在Swift 2.0
中引入的协议扩展改变了一切。伴随Where Clauses
的力量,这个新协议特性使我们想象一个没有类和多态的全新世界。
首先,作为一个副作用协议扩展消除了模拟测试,一个我认为丑陋的和不必要的。模拟是很糟糕的,协议扩展是伟大的并且可以做同样的事情。这是其他文章的主题,现在让我们来关注这个新特性如何改变我们的世界。
你已经知道值类型在Swift
是伟大的和强大的。因为编译器可以处理枚举、结构和类用同样的方式在底层,我们可以创建方法,属性和扩展在所有这些类型并且在运行时获得同样的性能。
只是为了说明这个功能是多么强大,想想看:在Swift
标准库、数组、集合和字典结构类型(实际上几乎所有Swift
标准库的结构与许多扩展)。所有这三个类型共享相同的CollectionType
协议。这个协议也由许多人共享,如字符串。
假设您希望创建一个数组和集合扩展。在Swift 1.x
,甚至在objective - c
中,你可以创建一个分类(称为扩展在Swift
中)为这个数组和为集合创建另一个分类,在这种情况下你可以开始复制代码。现在,随着协议扩展您可以为CollectionType
和所有的类创建一个扩展,并且实现这个协议获得免费的新功能。
但是等一下,你可能不想给这个函数所有CollectionType
,因为字典和字符串也会拥有它。没有问题,Where Clause
(即约束)你可以做到在一行代码中,在协议扩展上定义,将只作用于一个单一的元素类型的集合。
请注意,协议扩展和创建协议继承(或层次)是完全不同的。就像子类化一个类的层次结构,这并不是什么新鲜事物,Obj-C
已经存在。Swift
j叫(Extension
)扩展,我们以前用的叫分类(Category
),所以Swift 2.0
可以创建具体和抽象分类的协议,这是完全不同于协议继承。
花点时间思考这个新特性多么伟大,它可以打破范式和开放我们的世界的可能性。有些人可能会说不是太多,而且他们可能会考虑如何达到类似的行为,在其他语言编码一次。这不是重点。讨论一种语言没有多少胶水代码可以使用来达到相同的行为。讨论语言是它的语法和模式如何改变我们的思维和编写方式。
Swift 2.0
这个协议特性足以把我们跳出的多态性和类的盒子。记住,类试图说明这个真实的世界,但是他们有很多问题,如单链,这不是现实世界是如何工作的。语言像c++
这样尝试用多重继承给类一点力量,但是……OMG……你知道,这个尝试可能是有史以来最糟糕的特性之一。
简而言之,OOP(面向对象编程)试图重现真实世界结构和创建新的编程范式,但这并不是现实世界的工作方式。现在流行一种新的方式思考,一种新的方式来处理现实和转录真实世界的东西进入我们的小编程世界。
总结
从这篇文章中,记住下面这几件事,将是非常美好的:
Swift
的性能来自编译器
-
Swift 2.0
即将改变我们的范例 -
Swift
是未来
我将开始写一系列关于Swift
的文章,谈论它的新特性,秘密,分享Playgrounds
和算法。