Swift思量与初探:我须要学习Swift吗?

最近,除了N多的基于Swift的服务端开发框架,笔者不禁深思,到底该这么评价Swift呢?不能否认,在iOS的开发领域,Swift是比OJC拥有着优点,那么在通用语言这个层次上比较时,它又如何呢?html

Introduction

Apple 在推出 Swift 时就将其冠以先进,安全和高效的新一代编程语言之名。前两点在 Swift 的语法和语言特性中已经表现得淋漓尽致:像是尾随闭包,枚举关联值,可选值和强制的类型安全等都是 Swift 显而易见的优势。git

Comparison

近来Swift与Rust都挺好的,一个背靠Apple,一个是Mozilla的亲儿子。不能否认这两者都是工程领域的集大成者,不过笔者认为Swift是会比D或者Rust具备更大的可用性与吸引力,固然,他们的瞄准的目标点也不同。D与Rust适合于那些长期使用C++而且已经适应了要去掌握N多的语法与概念的,可是想要使用些更加清晰明了与安全的语言。这类型的开发者每每从事着相似于游戏引擎、编译器、加解密库、HTML渲染引擎等等相似的工做。github

Swift呢,更多意义上是一门面向于应用编程的语言,它很容易上手,在某些方面它应该与Go、Java、Python以及C#相提并论。不过Swift比这些会更容易开始学习,它的helloworld只须要一行代码就行了,而且它是支持函数的(不像Java那样彻底的OO)。你不须要学习任何的类与对象的知识就能够开始撰写简易的Swift的代码。基于此,Swift是更合适用做一种教学语言的,它还有像脚本语言同样的交互环境,也就是REPL以及Xcode自己提供的PlayGround。objective-c

综上所述,Swift拥有着被普遍使用以及当作第一学习语言的潜质。而且,Swift并非像PHP那样的语法特性较少的语言,它拥有足够的深度来知足Rust或者D这样的用户的需求。与Go相比的话,Go背靠Google,也是个很是容易上手的语言,而且号称自带并发。Swift在语法层次上会更加高级,而且Swift并无使用GC机制,所以能够与C更好地相兼容。也就是说,你能够用Swift编写任何的库来供任何语言使用,只要这些语言可使用C的库。这些特质保证了Swift拥有着比Java、C#、Python、Ruby以及Go更广阔的适用范围。后面这几个家伙,由于有GC的存在,不适合为其余语言提供基本库。我也很喜欢Go,可是毫无疑问,Swift会是个更加严谨与安全的语言。类型检测系统会帮助处理不少的错误,Go目前是很合适于Web开发可是不适合科学计算与游戏引擎这些你必需要大量自定义操做符来处理向量啊、矩阵运算这样的。编程

所以,Swift能够被定义为一个安全而且用户友好的语言,而且能够像脚本语言那样方便实验与使用。swift

Performance

Swift 具备一门高效语言所须要具有的绝大部分特色。与 Ruby 或者 Python 这样的解释型语言不须要再作什么对比了,相较于其前辈的 Objective-C,Swift 在编译期间就完成了方法的绑定,所以方法调用上再也不是相似于 Smalltalk 的消息发送,而是直接获取方法地址并进行调用。虽然 Objective-C 对运行时查找方法的过程进行了缓存和大量的优化,可是不能否认 Swift 的调用方式会更加迅速和高效。缓存

另外,与 Objective-C 不一样,Swift 是一门强类型的语言,这意味 Swift 的运行时和代码编译期间的类型是一致的,这样编译器能够获得足够的信息来在生成中间码和机器码时进行优化。虽然都使用 LLVM 工具链进行编译,可是 Swift 的编译过程相比于 Objective-C 要多一个环节 -- 生成 Swift 中间代码 (Swift Intermediate Language,SIL)。SIL 中包含有不少根据类型假定的转换,这为以后进一步在更低层级优化提供了良好的基础,分析 SIL 也是咱们探索 Swift 性能的有效方法。安全

最后,Swift 具备良好的内存使用的策略和结构。Swift 标准库中绝大部分类型都是 struct,对值类型的 使用范围之广,在近期的编程语言中可谓数一数二。本来值类型不可变性的特色,每每致使对于值的使用和修改意味着建立新的对象,可是 Swift 巧妙地规避了没必要要的值类型复制,而仅只在必要时进行内存分配。这使得 Swift 在享受不可变性带来的便利以及避免没必要要的共享状态的同时,还可以保持性能上的优秀。闭包

编译器优化

Swift 编译器十分智能,它能在编译期间帮助咱们移除不须要的代码,或者将某些方法进行内联 (inline) 处理。编译器优化的强度能够在编译时经过参数进行控制,Xcode 工程默认状况下有 Debug 和 Release 两种编译配置,在 Debug 模式下,LLVM Code Generation 和 Swift Code Generation 都不开启优化,这能保证编译速度。而在 Release 模式下,LLVM 默认使用 "Fastest, Smallest [-Os]",Swift Compiler 默认使用 "Fast [-O]",做为优化级别。咱们另外还有几个额外的优化级别能够选择,优化级别越高,编译器对于源码的改动幅度和开启的优化力度也就越大,同时编译期间消 耗的时间也就越多。虽然绝大部分状况下没有问题,可是仍然须要小心的是,一些优化等级采用的是激进的优化策略,而禁用了一些检查。这可能在源码很复杂的情 况下致使潜在的错误。若是你使用了很高的优化级别,请再三测试 Release 和 Debug 条件下程序运行的逻辑,以防止编译器优化所带来的问题。并发

值得一提的是,Swift 编译器有一个颇有用的优化等级:"Fast, Whole Module Optimization",也即 -O -whole-module-optimization。在这个优化等级下,Swift 编译器将会同时考虑整个 module 中全部源码的状况,并将那些没有被继承和重载的类型和方法标记为 final,这将尽量地避免动态派发的调用,或者甚至将方法进行内联处理以加速运行。开启这个额外的优化将会大幅增长编译时间,因此应该只在应用要发布的时候打开这个选项。

虽然如今编译器在进行优化的时候已经足够智能了,可是在面对编写得很是复杂的状况时,不少本应实施的优化可能失效。所以保持代码的整洁、干净和简单,可让编译器优化良好工做,以获得高效的机器码。

注释与换行

注释

请将你的代码中的非执行文本注释成提示或者笔记以方便你未来阅读。Swift 的编译器将会在编译代码时自动忽略掉注释部分。

Swift 中的注释与C 语言的注释很是类似。单行注释以双正斜杠做(//)为起始标记:

// 这是一个注释

你也能够进行多行注释,其起始标记为单个正斜杠后跟随一个星号(/),终止标记为一个星号后跟随单个正斜杠(/):

/* 这是一个, 多行注释 */

与C 语言多行注释不一样,Swift 的多行注释能够嵌套在其它的多行注释之中。你能够先生成一个多行注释块,而后在这个注释块之中再嵌套成第二个多行注释。终止注释时先插入第二个注释块的终止标记,而后再插入第一个注释块的终止标记:

/* 这是第一个多行注释的开头 /* 这是第二个被嵌套的多行注释 */ 这是第一个多行注释的结尾 */

经过运用嵌套多行注释,你能够快速方便的注释掉一大段代码,即便这段代码之中已经含有了多行注释块。

Objective-C混合编程

参考资料

  • 从Objective-C到Swift

  • swift与objective-c混编

  • Swift and Objective-C in the Same Project

Swift 与 Objective-C混合调用示意图

Swift类引用Objective-C文件

由于Swift没有内嵌的头文件机制,所以Swift调用Objective-C须要一个名为“<工程名>-Bridging-Header.h”的桥接头文件。桥接头文件的做用是为Swift调用Objective-C对象搭建一个桥,它的命名必须是“<工程名>- Bridging-Header.h”,咱们须要在桥接头文件中引入Objective-C头文件,全部的Swift类会自动引用这个头文件。

桥接文件

桥接文件设置

  • OJC类以下:

//
//  ObjcFunc.h
//

# import <Foundation/Foundation.h>

@interface ObjcFunc : NSObject

-(NSString*)sayHello:(NSString*)greeting withName: (NSString*)name;

@end

//
//  ObjcFunc.m
//

# import "ObjcFunc.h"

# import "CombinedProgram-Swift.h"

@implementation ObjcFunc

- (NSString*)sayHello:(NSString*)greeting withName: (NSString*)name{

    NSString *string = [NSString stringWithFormat:@"Hi,%@ %@.",name,greeting];

    return string;

  }

@end
  • Swift类中调用

import Foundation
@objc class SwiftFunc: NSObject {
  func sayHello() -> Void {
  var obj : ObjcFunc = ObjcFunc()
  println(obj.sayHello("Hello", withName: "Swift"));
  return
  }
}

Objective-C类引用Swift文件

(1)在Building Settings -> Packaging -> Defining中选定Module Name;

(2)在OJC的头文件中引入:#import "{ModuleName}-swift.h"

SwiftFunc* obj = [[SwiftFunc alloc] init];
[obj sayHello];

有时候会发现Xcode没法自动生成*-Swift.h文件,能够参考StackOverflow上的这篇文章。该文章总结下来,咱们须要进行如下两大步检测:

(1)检测你的Xcode的配置

Product Module Name : myproject

Defines Module : YES

Embedded Content Contains Swift : YES

Install Objective-C Compatibility Header : YES

sObjective-C Bridging Header : $(SRCROOT)/Sources/SwiftBridging.h

(2)检查你的Swift类是否正规

要保证你的Swfit类中已经使用@objc关键字声明了一个继承自NSObject的类。Xcode不会为存在任何编译错误的类进行编译操做。

(3)忽略Xcode的报错,先编译一下

语法要点

! VS ?

在Swift中常常看到!与?两个操做符,譬如在类型转换、可选类型构造中都用到,用Apple官方的话说:

It may be easiest to remember the pattern for these operators in Swift as: ! implies “this might trap,” while ?indicates “this might be nil.”

就是!操做符表示我无论你编译器,我确定要这么作,那么有可能致使运行时崩溃。而?操做符表示这个多是nil,你帮我查查有没有进行完备的空检查。

Reference

Tutorial & Docs

  • 中文版 Apple 官方 Swift 教程《The Swift Programming Language》

  • Swift学习笔记

Forum & Lessons

Blog & News

Book & Resources

相关文章
相关标签/搜索