写点什么

Swift 编程语言

  • 2014-11-28
  • 本文字数:4572 字

    阅读完需:约 15 分钟

在过去的几年中,移动应用程序风靡全世界并且已经改变了我们使用互联网进行工作或者休闲的方式。为了创建移动应用程序,各种技术应运而生,同时开发过程也开始将其作为一等公民来对待。尽管移动似乎已经无处不在了,但是它的未来才刚刚开始。我们正面对着新一代的移动设备,例如可穿戴设备以及组成物联网的大量移动工具。我们将会面对新的用来展示数据和接受命令的用户界面。同时,我们将会看到越来越多的公司真正地实现移动优先。所有的这一切都将会影响我们在未来的几年中设计、开发和测试软件的方式。

苹果公司最近推出了 Swift 1.0——一门针对 iOS 和 OSX 开发的新编程语言。不要将苹果的 Swift 与老的并行脚本语言混淆。Swift 的目标是让 iOS 和 OSX 开发变得更简单,更有乐趣。在本文中,我将会解释我认为 Swift 所具有的最具杀伤力的5个特性以及我为什么会这样认为的原因,虽然这些特性现在依然出于测试阶段,但是却值得我们一试。

苹果已经拥有了一门编程语言——Objective-C。那么为什么还要引入另一门编程语言呢?这是因为虽然 Objective-C 在被创建的时候可能已经非常地独特,同时也很先进,但是它现在并没有当今语言的味道。例如,在消费者方面像 Ruby 这样的脚本语言已经被广泛采用,这很大程度上得益于它干净的语法。在企业领域,具有类型推理能力的强类型(类型安全的)语言更受欢迎,为了将函数式编程语言所具有的函数即对象、Lambda 表达式等经典特性引入进来,C#和 Java(或者 Scala)等语言都做出了大量的努力。Objective-C 一直都缺少这类东西,例如干净的语法(和语法糖),类型推理。而 Swift 正是为了填补这个空白。

这并不是说 Objective-C 并不是一门优秀的编程语言。实际上,它是一门优秀的语言。但是我确实看到有足够的空间可以成功地替代 Objective-C。进一步讲,同时也要感谢 Swift 的优秀,我认为 Swift 一定会像野火那样迅速蔓延开来。

现在,就让我们看看 Swift 都提供了什么吧。从语言的角度看,Swift 是非常了不起的。苹果借鉴了 Scala 和 C#这些现代语言的优点,构建了一门非常简单,但是功能非常强大的语言。它非常完美地融合了面向对象和函数式编程范式——但是说 Swift 是一门函数式语言是一种极大的延伸。下面就让我们看看 Swift 最具杀伤力的 5 个特性。

从语法上讲 Swift 非常华丽。它是一门非常简单、干净的语言,同时可读性也非常好,即使以现在的标准来衡量也是如此。你马上就会发现在设计一门语言的时候简单性是一个关键要素。例如,大家所熟知的语句末尾的分号。苹果决定将分号作为可选的,虽然这看起来相关性并不是非常强,但是它却让我们看到了苹果为了尽可能地保持语法干净所做出的努力。

var message = “Hello World” “The message is \(message)” //The message is Hello world var a = 1, b = 2 “The sum is \(a + b)” //The sum is 3 循环

复制代码
var length = 10
for i in 0..<length do="" i="" something="" with=""></length>

数组

复制代码
var list = ["a", "b"]
list += ["c", "d"]

以上仅是 Swift 为简单性提供语言支持的一部分示例。需要注意的是你依然可以使用 Array 类的“append”方法连接数组,而苹果之所以走了额外的一英里将其构建为语言的一部分目的是为了展示他们设计 Swift 的目标。

如果你想学习 Swift 并对一些这样的示例代码进行测试,那么可以尝试下Xcode 6,它的代码实时预览(Playground)功能太酷了,简直无法用语言形容。实时预览功能让你能够实时地随着你的输入对代码进行测试。它会执行你在开发环境中输入的所有内容,提供与变量值、函数调用返回值以及特定代码块被执行的次数相关的详细信息。打开 Xcode 6 中的实时预览功能非常简单:

(单击放大图片)

下面的图片展示了实时预览功能:

(单击放大图片)

#2: 函数是一等对象

越来越多的语言将函数作为一等公民并支持高级函数。例如,最近发布的Java 8 引入了Lambda 表达式。它的理念很简单,就是让函数可以接受函数类型的参数,同时也可以将函数作为返回值。理念的简单性奠定了它强大的基础,因为这样支持更多的抽象。例如,我们可以将一个“过滤(filter)”函数应用到一个数组,该过滤函数接受数组中的每一个条目作为参数,通过特定的标准对条目进行判定从而完成对给定数组的过滤。使用更加通用的方法的关键是能够接受函数类型的参数。下面就让我们看看定义函数的语法。

Swift 定义函数的语法与传统的 Haskell 这样的函数型语言相似,但并不完全一样。箭头(->)的左边是参数以及参数的类型,右边是返回值类型。在本文的示例中,我们想要过滤一个数字列表,因而基于一个给定的数字我们会返回一个 Bool 类型。在这种情况下,函数看起来可能是这样的:

复制代码
(Item:Int) -> Bool

这段代码的意思是接受一个 Int 类型的参数,返回一个 Bool 类型的值。很显然,你可以包含多个参数,但是不太明显的是,你还可以返回多个值,而这不需要创建一个容器对象。在后面的示例中,函数会返回一个元组 。

一个过滤整数的函数定义可能是这样:

复制代码
funct bigNumbersOnly (item:Int) -> Bool {
return item > 3
}

现在,我们已经创建了自己的过滤函数,下面让我们看看可以接受函数参数类型的“filter”函数。

复制代码
var numbers = [1, 2, 3, 4, 5]
var bigOnes = numbers.filter(bigNumbersOnly)

在这个示例中,filter 是一个高阶函数,因为它的参数类型是函数。在 Swift 中,函数也是对象,这意味着我们可以定义内联函数:

复制代码
var numbers = [1, 2, 3, 4, 5]
var bigOnes = numbers.filter({(item:Int) -> Bool in return item > 3})

或者我们也可以将函数赋值给某个变量,稍后再使用它:

复制代码
//define two variables of type function
var biggies = {(item:Int) -> Bool in return item > 3 }
var threes = {(item:Int) -> Bool in return item == 3 }
//decide which one to apply at runtime
var result = numbers.filter(onlyThrees ? threes : biggies)

当今,将函数作为对象,让用户能够像使用参数那样引用、传递函数已经成为一种优美的标准。而 Swift 实现方式的简洁性依然是一个值得称道的地方,这一核心概念配合类型推理可以让你事半功倍。

#3: 强类型与类型推理

在企业开发领域,我们非常习惯于使用强类型(或者说类型安全的)语言。强类型语言通常会给我们带来一点额外的自信,因为它能够在编译时进行错误检查,如果这些语言也能够支持类型推理那么将会是一种非常好的体验。例如,可以这样:

复制代码
//Without Type inference
var x:String = "bar"
//With Type inference
var y = "bar"

注意,第二行的语句并没有声明变量的类型。因为 Swift 知道“bar”是一个字符串,所以我们并不需要显式地定义它的类型,当然我们也可以指定,正如第一个语句那样。这看起来好像并没有特别大的作用,但是如果推理的是函数的类型那么它就会变得十分有趣。

那么如果不使用类型我们应该如何定义之前例子中的函数呢?下面的代码展现了 Swift 的实现:

复制代码
//$0 will map to the first parameter, $1 to the second...
var result = numbers.filter({ return $0 == 3})

没有比这更简洁的了!如果你的参数不止一个,同时想要通过名字引用参数,那么可以这样做:

复制代码
{a, b in return a > b }

#4 泛型

Swift 提供的另一个非常便利的特性是泛型。在企业开发领域,泛型首先被引入到了 C#中,在获得了大量的关注之后 Java 也引入了该特性。使用泛型可以让开发者消除类型转换,因为编译器能够运行特定的类型检查,而对于不支持泛型的语言而言这是无法做到的。虽然刚开始将泛型引入 C#的时候确实产生了一些争论,但是现在它已经被 C#和 Java 社区所普遍接受。

泛型提供了一种方式可以让我们推迟类型的定义,通常(但不限于)是参数和返回值的类型。虽然它听起来很复杂,但是实际上通过一个简单的示例我们就能非常容易地理解它。

复制代码
//At the moment of creating this function
//I am not defining what T is. The actual
//Type of T will be deferred to the call
//of the doNothing function.
func doNothing (item:T) -> T {
return item
}
//When I call doNothing, I am implicitly
//setting the type of T to the Type of the
//parameter I am sending. In this case,
//an Array.
//Notice how the compiler knows, that the
//return type is an Array.
doNothing([1, 2, 3]).count

虽然上面并不是一个真实的例子,但是通过它我们能够看到在编译时确定数组内部元素类型的便利。下面是一个更简单的示例,注意编译器是如何知道数组是包含字符串类型的:

复制代码
var list = ["hello", "world"]
list[0].uppercaseString //HELLO

泛型的使用范围并没有被限定于参数,我们也可以定义泛型类、枚举和结构。事实上,在前面的示例中,list 的类型是 Array

你可能会将 Swift 中的泛型与 Objective-C 中的协议类比,虽然它们的语法非常相似,但是概念是非常不同的。Objective-C 并不支持泛型。协议提供了一种方式去声明一个确定的实现符合某个消息契约,但是契约必须预先指定。例如,使用协议你并不能强迫数组中的所有条目都是同一类型的(无论是什么类型),但是使用泛型能够做到。除了概念上的不同之外,Swift 并不支持协议,就像 Objective-C 不支持泛型一样。

#5 元组

元组是非常简单的概念,你可以定义一个有序的值组。当你需要将多个值作为一个参数来回传递、或者被调用的函数需要返回多个值的时候元组会非常有用。元组并不需要我们为它的值定义任何类型,编译时会完成所有的类型推理和类型检查工作。定义元组的语法如下:

复制代码
(1, "Two", ["Three"])

在上面的例子中,我们创建了一个带有三个值的元组,第一个是一个整数,第二个是字符串,第三个是一个字符串类型的数组。乍一看这很像一个数组,但概念完全不同。你不能从一个元组中删除或者向里追加元素,同时注意编译器是如何知道每一个值的确切类型的:

你可以通过元素在元组内部的位置引用它的值,正如图片所提示的那样;或者你也可以为每一个值指定一个名称。如果一个函数需要返回几个值,那么这是非常方便的,同时它也能让我们避免定义那些特定于某个函数的类或者结构。下面让我们看一个这样的例子:

复制代码
func info(items:[Int]) -> (avg:Int, min:Int, max:Int) {
var sum = items.reduce(0, { $0 + $1 })
var min = items.reduce(Int.max, { $0 > $1 ? $1 : $0})
var max = items.reduce(Int.min, { $0 < $1 ? $1 : $0})
return (sum / items.count, min, max)
}
var result = info([1, 2, 3, 4, 5, 6])
result.avg //3
result.min //1
result.max //6

元组提供了一种非常简单的使用多个值的方法,让我们省去了定义一个特定的类或者结构的额外工作。

还有更多

除了上面介绍的特性之外 Swift 还有很多其他的优秀特性值得我们一看,例如属性观察器、可选链接以及扩展。

我相信 Swift 具备快速成为一门流行的 iOS 和 OSX 编程语言所需要的所有必须条件,无论是在企业领域还是在消费者领域。强类型和类型推理特性将会让它非常适合于企业开发,而它的简单性和干净的语法则会吸引那些从事消费者项目的开发人员。

关于作者

Gustavo Machado是 KidoZen 公司的工程副总裁,他的工作是领导大家开发公司的下一代企业移动平台。 他在通过不同的技术开发高度分布式系统以及敏捷实践方面拥有丰富的经验。他一直在积极地维护自己的博客,同时他的twitter 帐号是@machadogj。

查看英文原文: Swift Programming Language

2014-11-28 07:357081
用户头像

发布了 321 篇内容, 共 119.6 次阅读, 收获喜欢 19 次。

关注

评论

发布
暂无评论
发现更多内容

架构实战营作业模块一

五只羊

架构实战营

iOS工程师如何恍然大悟?

程序员 IT 编程之路 iOS 知识体系

两者可兼得,在IDEA中使用Git!

Ayue、

git 学习

成功收到美团、字节、蚂蚁Offer后!我把狂刷 5 遍的面试题整理出来了!

Java 程序员 架构 面试

扩展Elasticsearch客户端简化ES查询(.net core/framework)

Spook

论文解读丨图神经网络应用于半结构化文档的命名实体识别和关系提取

华为云开发者联盟

文档 识别 图神经网络 半结构化文档 关系提取

数字货币这波热潮,各国都舍不得错过

CECBC

[架构实战营]模块一作业

xyu

#架构实战营

接下来的40年,碳中和对我们来说意味着什么?

CECBC

简单四步学会在数字孪生可视化场景中创建小地图!

ThingJS数字孪生引擎

大前端 地图 物联网 可视化 数字孪生

FIL币价值与未来, FIL币价值预估

万字长文,Spark 架构原理和RDD算子详解一网打进!

云祁

大数据 spark 7月日更

一个成功的 Git 分支模型如何构建?

白亦杨

Apache ShardingSphere 邀您相约 Open Source Day

SphereEx

怎么在linux系统下安装Nginx?一分钟学会!

小桃

Linux 网络安全 系统

架构实战营 -- 模块1作业

发酵的死神

查看Linux端口占用,并关掉相关进程。

学神来啦

云计算 Linux 运维

视频云峰会|“科技 X 艺术” 的颗粒度体验是什么?

阿里云CloudImagine

阿里云 AR 艺术 摄影 vr

虚拟币合约交易平台搭建,永续合约交易系统源码

模块八作业

c

架构实战营

SQL巩固测试题

Flychen

模块一作业

燕燕 yen yen

#架构实战营

367W字!京东商城Java架构师设计的亿级高并发秒杀手抄笔记

Java架构追梦

Java 架构 秒杀系统 亿级并发 京东商城

CDH的安装(三)

大数据技术指南

CDH 7月日更

Hive学习笔记(二)

五分钟学大数据

hive 7月日更

5W1H聊开源之Why——为什么要参与开源?

禅道项目管理

开源 项目

官宣!ElasticJob 3.0.0 版本正式发布

SphereEx

视频云会议已成未来发展必然趋势

anyRTC开发者

音视频 WebRTC 视频会议 云视频

网络攻防学习笔记 Day67

穿过生命散发芬芳

网络攻防 7月日更

面试扣分点:什么是鸭子类型?

揭秘版权保护下的视频隐形水印算法(上篇)

拍乐云Pano

Swift编程语言_移动_Gustavo Machado_InfoQ精选文章