61阅读

苹果编程语言swift-苹果WWDC落幕 iOS 8新OS X及编程语言Swift亮相

发布时间:2018-05-06 所属栏目:苹果编程

一 : 苹果WWDC落幕 iOS 8新OS X及编程语言Swift亮相

面向开发者,苹果公司提供了一系列新的服务,包括新版SDK(软件开发套装)、新版开发工具包、新的编程语言等。针对开发者,苹果公司还推出了对休闲游戏进行优化的工具SpriteKit,以及最新的开发工具集Xcode。

 iOS8 OSX Swift 苹果发布会

苹果WWDC落幕 iOS 8、新OS X及编程语言Swift亮相

6月3日消息,苹果公司于北京时间今日凌晨1时举行全球开发者大会(WWDC),推出了全新的协同操作系统iOS 8及Mac系统OS X 10.10,此外,还推出了全新的开发者编程语言Swift(雨燕)。

除了外观上的改变,iOS 8还加入了健康监察功能Health Kit,可监察用家的心跳、血压及睡眠等健康数据。另外,亦加入智能家居功能HomeKit,用户可透过iPhone等装置控制灯光、门锁及车库大门开关等。

此外,苹果终于在iOS 8系统中开放了第三方输入法的权限,相信这一变化会让越狱用户的比例进一步降低。

而新的Mac操作系统则命名为OS X Yosemite,操作界面全面扁平化及毛玻璃化,同时增加多项与iOS装置协作的功能,例如可透过AirDrop与iOS装置交换资料等。

面向开发者,苹果公司提供了一系列新的服务,包括新版SDK(软件开发套装)、新版开发工具包、新的编程语言等。

新版SDK新增了4000个API(应用程序接口),开发者可以借此开发功能更为丰富的应用;去年推出的指纹识别功能Touch ID将被开放给开发者。同时,开发者还将拥有更多的摄像头API(应用程序接口)。

苹果公司还希望进入智能家居领域,推出了HomeKit功能,希望让iPhone成为家里智能设备的遥控器。

苹果在此次WWDC上推出的最新编程语言Swift成为开发者欢呼雀跃的亮点。苹果公司表示,与现有的开发语言C语言和Python相比,Swift更具优势,编程更快速,更好地实现所想要的效果。

此外,针对开发者,苹果公司还推出了对休闲游戏进行优化的工具SpriteKit,以及最新的开发工具集Xcode。

而此前被大部分媒体报道称或将在此次WWDC上出现的iPhone 6则没有出现。(安东)

二 : 苹果编程语言Swift简介

Swift是什么?

Swift是苹果于WWDC 2014发布的编程语言,The Swift Programming Language的原话:

Swift is a new programming language for iOS and OS X apps that builds on the best of C and Objective-C, without the constraints of C compatibility.  Swift adopts safe programming patterns and adds modern features to make programming easier, more flexible and more fun.  Swift’s clean slate, backed by the mature and much-loved Cocoa and Cocoa Touch frameworks, is an opportunity to imagine how software development works.  Swift is the first industrial-quality systems programming language that is as expressive and enjoyable as a scripting language.

简单的说:

Swift用来写iOS和OS X程序。(www.61k.com)(估计也不会支持其它屌丝系统)  Swift吸取了C和Objective-C的优点,且更加强大易用。  Swift可以使用现有的Cocoa和Cocoa Touch框架。  Swift兼具编译语言的高性能(Performance)和脚本语言的交互性(Interactive)。

Swift语言概览

基本概念

注:这一节的代码源自The Swift Programming Language中的A Swift Tour。

Hello, world

类似于脚本语言,下面的代码即是一个完整的Swift程序。

println("Hello, world") 变量与常量

Swift使用var声明变量,let声明常量。

var myVariable = 42  myVariable = 50  let myConstant = 42

类型推导

Swift支持类型推导(Type Inference),所以上面的代码不需指定类型,如果需要指定类型:

let explicitDouble : Double = 70

Swift不支持隐式类型转换(Implicitly casting),所以下面的代码需要显式类型转换(Explicitly casting):

let label = "The width is " let width = 94 let width = label + String(width)

字符串格式化

Swift使用\(item)的形式进行字符串格式化:

let apples = 3  let oranges = 5  let appleSummary = "I have \(apples) apples."  let appleSummary = "I have \(apples + oranges) pieces of fruit."

数组和字典

Swift使用[]操作符声明数组(array)和字典(dictionary):

var shoppingList = ["catfish", "water", "tulips", "blue paint"]  shoppingList[1] = "bottle of water"  var occupations = [  "Malcolm": "Captain",  "Kaylee": "Mechanic",  ]  occupations["Jayne"] = "Public Relations"

一般使用初始化器(initializer)语法创建空数组和空字典:

let emptyArray = String[]()  let emptyDictionary = Dictionary<String, Float>()

如果类型信息已知,则可以使用[]声明空数组,使用[:]声明空字典。

控制流

概览

Swift的条件语句包含if和switch,循环语句包含for-in、for、while和do-while,循环/判断条件不需要括号,但循环/判断体(body)必需括号:

let individualScores = [75, 43, 103, 87, 12] var teamScore = 0 for score in individualScores {  if score > 50 {  teamScore += 3  } else {  teamScore += 1  } }

可空类型

结合if和let,可以方便的处理可空变量(nullable variable)。对于空值,需要在类型声明后添加?显式标明该类型可空。

var optionalString: String? = "Hello" optionalString == nil var optionalName: String? = "John Appleseed" var gretting = "Hello!" if let name = optionalName {  gretting = "Hello, \(name)" }

灵活的switch

Swift中的switch支持各种各样的比较操作:

let vegetable = "red pepper"  switch vegetable {  case "celery":  let vegetableComment = "Add some raisins and make ants on a log."  case "cucumber", "watercress":  let vegetableComment = "That would make a good tea sandwich."  case let x where x.hasSuffix("pepper"):  let vegetableComment = "Is it a spicy \(x)?"  default:  let vegetableComment = "Everything tastes good in soup."  }

其它循环

for-in除了遍历数组也可以用来遍历字典:

let interestingNumbers = [  "Prime": [2, 3, 5, 7, 11, 13],  "Fibonacci": [1, 1, 2, 3, 5, 8],  "Square": [1, 4, 9, 16, 25],  ]  var largest = 0  for (kind, numbers) in interestingNumbers {  for number in numbers {  if number > largest {  largest = number  }  }  }  largest

while循环和do-while循环:

var n = 2  while n < 100 {  n = n * 2  }  n  var m = 2  do {  m = m * 2  } while m < 100  m

Swift支持传统的for循环,此外也可以通过结合..(生成一个区间)和for-in实现同样的逻辑。

var firstForLoop = 0  for i in 0..3 {  firstForLoop += i  }  firstForLoop  var secondForLoop = 0  for var i = 0; i < 3; ++i {  secondForLoop += 1  }

注意:Swift除了..还有...:..生成前闭后开的区间,而...生成前闭后闭的区间。

函数和闭包

函数

Swift使用func关键字声明函数:

func greet(name: String, day: String) -> String {  return "Hello \(name), today is \(day)."  } greet("Bob", "Tuesday")

通过元组(Tuple)返回多个值:

func getGasPrices() -> (Double, Double, Double) {  return (3.59, 3.69, 3.79)  }  getGasPrices()

支持带有变长参数的函数:

func sumOf(numbers: Int...) -> Int {  var sum = 0  for number in numbers {  sum += number  }  return sum  }  sumOf()  sumOf(42, 597, 12)

函数也可以嵌套函数:

func returnFifteen() -> Int {  var y = 10  func add() {  y += 5  }  add()  return y  }  returnFifteen()

作为头等对象,函数既可以作为返回值,也可以作为参数传递:

func makeIncrementer() -> (Int -> Int) {  func addOne(number: Int) -> Int {  return 1 + number  }  return addOne  }  var increment = makeIncrementer()  increment(7)

func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool {  for item in list {  if condition(item) {  return true  }  }  return false  }  func lessThanTen(number: Int) -> Bool {  return number < 10  }  var numbers = [20, 19, 7, 12]  hasAnyMatches(numbers, lessThanTen)

闭包

本质来说,函数是特殊的闭包,Swift中可以利用{}声明匿名闭包:

numbers.map({  (number: Int) -> Int in  let result = 3 * number  return result  })

当闭包的类型已知时,可以使用下面的简化写法:

numbers.map({ number in 3 * number })

此外还可以通过参数的位置来使用参数,当函数最后一个参数是闭包时,可以使用下面的语法:

sort([1, 5, 3, 12, 2]) { $0 > $1 } 类和对象 创建和使用类

Swift使用class创建一个类,类可以包含字段和方法:

class Shape {  var numberOfSides = 0  func simpleDescription() -> String {  return "A shape with \(numberOfSides) sides."  }  }

创建Shape类的实例,并调用其字段和方法。

var shape = Shape()  shape.numberOfSides = 7  varshapeDescription = shape.simpleDescription()

通过init构建对象,既可以使用self显式引用成员字段(name),也可以隐式引用(numberOfSides)。

class NamedShape {  var numberOfSides: Int = 0  var name: String  init(name: String) {  self.name = name  }  func simpleDescription() -> String {  return "A shape with \(numberOfSides) sides."  }  }

使用deinit进行清理工作。

继承和多态

Swift支持继承和多态(override父类方法):

class Square: NamedShape {  var sideLength: Double  init(sideLength: Double, name: String) {  self.sideLength = sideLength  super.init(name: name)  numberOfSides = 4  }  func area() -> Double {  return sideLength * sideLength  }  override func simpleDescription() -> String {  return "A square with sides of length \(sideLength)."  }  }  let test = Square(sideLength: 5.2, name: "my test square")  test.area()  test.simpleDescription()

注意:如果这里的simpleDescription方法没有被标识为override,则会引发编译错误。

属性

为了简化代码,Swift引入了属性(property),见下面的perimeter字段:

class EquilateralTriangle: NamedShape {  var sideLength: Double = 0.0  init(sideLength: Double, name: String) {  self.sideLength = sideLength  super.init(name: name)  numberOfSides = 3  }  var perimeter: Double {  get {  return 3.0 * sideLength  }  set {  sideLength = newValue / 3.0  }  }  override func simpleDescription() -> String {  return "An equilateral triagle with sides of length \(sideLength)."  }  }  var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")  triangle.perimeter  triangle.perimeter = 9.9  triangle.sideLength

注意:赋值器(setter)中,接收的值被自动命名为newValue。

willSet和didSet

EquilateralTriangle的构造器进行了如下操作:

为子类型的属性赋值。 调用父类型的构造器。 修改父类型的属性。

如果不需要计算属性的值,但需要在赋值前后进行一些操作的话,使用willSet和didSet:

class TriangleAndSquare {  var triangle: EquilateralTriangle {  willSet {  square.sideLength = newValue.sideLength  }  }  var square: Square {  willSet {  triangle.sideLength = newValue.sideLength  }  }  init(size: Double, name: String) {  square = Square(sideLength: size, name: name)  triangle = EquilateralTriangle(sideLength: size, name: name)  }  }  var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")  triangleAndSquare.square.sideLength  triangleAndSquare.square = Square(sideLength: 50, name: "larger square")  triangleAndSquare.triangle.sideLength

从而保证triangle和square拥有相等的sideLength。

调用方法

Swift中,函数的参数名称只能在函数内部使用,但方法的参数名称除了在内部使用外还可以在外部使用(第一个参数除外),例如:

class Counter {  var count: Int = 0  func incrementBy(amount: Int, numberOfTimes times: Int) {  count += amount * times  }  }  var counter = Counter()  counter.incrementBy(2, numberOfTimes: 7)

注意Swift支持为方法参数取别名:在上面的代码里,numberOfTimes面向外部,times面向内部。

?的另一种用途

使用可空值时,?可以出现在方法、属性或下标前面。如果?前的值为nil,那么?后面的表达式会被忽略,而原表达式直接返回nil,例如:

let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional  square")  let sideLength = optionalSquare?.sideLength

当optionalSquare为nil时,sideLength属性调用会被忽略。

枚举和结构

枚举

使用enum创建枚举——注意Swift的枚举可以关联方法:

enum Rank: Int {  case Ace = 1  case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten  case Jack, Queen, King  func simpleDescription() -> String {  switch self {  case .Ace:  return "ace"  case .Jack:  return "jack"  case .Queen:  return "queen"  case .King:  return "king"  default:  return String(self.toRaw())  }  } }  let ace = Rank.Ace  let aceRawValue = ace.toRaw()

使用toRaw和fromRaw在原始(raw)数值和枚举值之间进行转换:

if let convertedRank = Rank.fromRaw(3) {  let threeDescription = convertedRank.simpleDescription()  }

注意枚举中的成员值(member value)是实际的值(actual value),和原始值(raw value)没有必然关联。

一些情况下枚举不存在有意义的原始值,这时可以直接忽略原始值:

enum Suit {  case Spades, Hearts, Diamonds, Clubs  func simpleDescription() -> String {  switch self {  case .Spades:  return "spades"  case .Hearts:  return "hearts"  case .Diamonds:  return "diamonds"  case .Clubs:  return "clubs"  }  } } let hearts = Suit.Hearts let heartsDescription = hearts.simpleDescription()

除了可以关联方法,枚举还支持在其成员上关联值,同一枚举的不同成员可以有不同的关联的值:

enum ServerResponse {  case Result(String, String)  case Error(String)  }  let success = ServerResponse.Result("6:00 am", "8:09 pm")  let failure = ServerResponse.Error("Out of cheese.")  switch success {  case let .Result(sunrise, sunset):  let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)."  case let .Error(error):  let serverResponse = "Failure... \(error)"  }

结构

Swift使用struct关键字创建结构。结构支持构造器和方法这些类的特性。结构和类的最大区别在于:结构的实例按值传递(passed by value),而类的实例按引用传递(passed by reference)。

struct Card {  var rank: Rank  var suit: Suit  func simpleDescription() -> String {  return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"  }  }  let threeOfSpades = Card(rank: .Three, suit: .Spades)  let threeOfSpadesDescription = threeOfSpades.simpleDescription()

协议(protocol)和扩展(extension) 协议

Swift使用protocol定义协议:

protocol ExampleProtocol {  var simpleDescription: String { get }  mutating func adjust()  }

类型、枚举和结构都可以实现(adopt)协议:

class SimpleClass: ExampleProtocol {  var simpleDescription: String = "A very simple class."  var anotherProperty: Int = 69105  func adjust() {  simpleDescription += " Now 100% adjusted."  } }  var a = SimpleClass()  a.adjust()  let aDescription = a.simpleDescription  struct SimpleStructure: ExampleProtocol {  var simpleDescription: String = "A simple structure"  mutating func adjust() {  simpleDescription += " (adjusted)"  }  }  var b = SimpleStructure()  b.adjust()  let bDescription = b.simpleDescription

扩展

扩展用于在已有的类型上增加新的功能(比如新的方法或属性),Swift使用extension声明扩展:

extension Int: ExampleProtocol {  var simpleDescription: String {  return "The number \(self)"  }  mutating func adjust() {  self += 42  }  }  7.simpleDescription

泛型(generics)

Swift使用<>来声明泛型函数或泛型类型:

func repeat(item: ItemType, times: Int) -> ItemType[] {  var result = ItemType[]()  for i in 0..times {  result += item  }  return result  }  repeat("knock", 4)

Swift也支持在类、枚举和结构中使用泛型:

enum OptionalValue{  case None  case Some(T)  }  var possibleInteger: OptionalValue= .None  possibleInteger = .Some(100)

有时需要对泛型做一些需求(requirements),比如需求某个泛型类型实现某个接口或继承自某个特定类型、两个泛型类型属于同一个类型等等,Swift通过where描述这些需求:

func anyCommonElements <T, U where T: Sequence,  U: Sequence, T.GeneratorType.Element: Equatable,  T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Bool {  for lhsItem in lhs {  for rhsItem in rhs {  if lhsItem == rhsItem {  return true  }  }  }  return false  }  anyCommonElements([1, 2, 3], [3])

Swift语言概览就到这里。参考资料如下:

Swift 教程

Apple 官方教程《The Swift Programming Language》  

PDF/ePUB/Kindle 格式下载Markdown 版中文版(翻译中)

Apple Swift 编程语言入门教程(@明哥选C)  

摘录、提取自《The Swift Programming Language》

系列教程:使用 Swift 开发 iOS 应用 (Jameson Quave)  

此为第一部分,第二部分、第三部分、第四部分、第五部分。

Swift 视频

Apple Swift 语言基础教程(@极客学院_jikexueyuan)  

共计 11 课时

Swift 开发视频教程【入门篇】(@51CTO学院)  

共计 40 课时

从 0 开始学 Swift(@传课网)  

共计 25 课时

Swift 系列视频教程 (Skip Wilson)  

已完成 4 部分,需梯子。

Swift 资料

Swift 编程语言资料大合集 (@CSDN_CODE)  

内容不错

Swift 学习资源(刘兰涛)  

分类细致

Swift 新手入门汇集帖 (@CocoaChina)  

内容不少

Swift 速查表 (Ray Wenderlich)  

PDF 下载地址

[PDF] Swift vs Scala 2.11  

对比详细

Swift 项目

Flappy Bird(Swift 版)  

目前 GitHub 上最火的开源 Swift 项目

2048(Swift 版)  

Star 数不少

GitHub 上的开源 Swift 项目  

已有近 500 个项目

Swift 网站

LearnSwift.tips  

内容不少

Learn Swift  

一个 Swift 博客,文章质量不错。

So So Swift  

一个 Swift 教程网站

Swift China(@老甘)  

中文网站

雨燕中文(@罗罗磊磊)  

中文网站

Let's Swift  

中文网站

三 : 为何谷歌和苹果都要开发自己的编程语言?

在即将于周一举行的全球开发者大会(WWDC)上,苹果公司即将分享一个鲜为人知的成功故事。[www.61k.com)大约1年前,苹果曾推出新的编程语言Swift,宣称其可帮助开发者更轻松地开发iPhone和Mac应用。开发者们为此欢呼不已。

苹果编程 为何谷歌和苹果都要开发自己的编程语言?

这种编程语言被称为Swift名副其实。苹果承诺Swift将令编程速度更快,应用也能更快地投入实际应用中。这种应用已经在许多开发者中引发共鸣,他们在Topcoder网站上举行Swift编程挑战赛,目前对Swift感兴趣的开发者已经达到3700人,并有望于今年年底达到2万人。

全球最大问答网站之一Stack Exchange对全球顶级开发者进行调查显示,Swift是开发者们最感兴趣的编程语言之一。去年11月份,一名男子通过教授其他人如何使用Swift,一个月净赚了6.6万美元。

但是苹果并非第一家推出自己编程语言的科技巨头。早在1991年,微软就已经推出可视化程序设计语言Visual Basic,它以Basic编程语言为基础,是图形用户界面最早、最受欢迎的编程语言。大约2009年,谷歌也推出了其自己的编程语言Go。

对于众多开发者来说,编程语言非常重要。而对苹果、谷歌甚至微软来说,每当发布新的编程语言时,都意味着对开发者们的习惯发起艰难挑战。因此,企业肯定会谨慎考虑,对吗?苹果和谷歌也必定从中赚取利益,对吧?

开发编程语言好处多

然而,事实并非如此。苹果与谷歌的编程语言有很多共同之处。谷歌的Go与苹果的Swift旨在解决开发者在旧版编程语言中遇到的问题。

Swift很像Objective-C,后者主导iOS编码,开发者很快就采用它。事实上,它与Objective-C如此相似,以至于Swift代码甚至可被用于同一种应用中。但是Objective-C已经诞生30多年了,而Swift则是一种现代化努力,确保应用开发更容易,运行速度更快。

与Swift类似,Go的目标也是帮助更轻松地建立复杂系统。而网络软件编程行业中的昔日老大C++与Python,已经无法满足谷歌要求。Go FAQ发言人称:“Go是在开发者对现有系统编程语言和环境感到失望的情况下应运而生的。”

自从Go诞生以来,编码者使用它更为轻松,但在我们称之为“云”的大数据中心时代,它依然存在很多编程语言在速度和性能方面的问题。作为一个开源项目,全世界的开发者都为Go的发展做出贡献,令其越来越好。

对于谷歌和苹果来说,推出自己的编程语言有助于他们更轻松地招募相关人才。比如,自从使用Go建立自己的服务器应用后,谷歌更容易招募到精通Go语言的开发者,他们只需要更少的培训即可承担重任。

此外,公司外部的开发者利用Swift或Go解决的任何问题,苹果与谷歌都可以应用到自己的业务中。但是最重要的部分是,这些语言被公开后,其唯一目的就是帮助开发者开发出更好的软件。

Swift快速崛起

云端应用监测与管理平台New Reli的高级软件工程经理乔纳森·卡隆(Jonathan Karon)说:“当然,Swift的承诺是让软件变得更加稳定。”更为稳定的软件意味着更好的应用体验,而更好的应用体验令苹果开发者感觉更好,iPhone看起来也更棒。

Swift已经取得早期成功,但是其依然需要不断改进,毕竟其诞生仅仅1年时间。Swift的高标准要求意味着它很难被用于在低端Macbook上写代码,并且还缺少很多功能。开发者中间也存在争议,Swift是否真的比Objective-C更快。

但是开发者们对Swift的未来发展非常看好。卡隆称,从企业角度来看,他发现New Reli客户大多保持他们现有的后端软件,但是他们正使用Swift开发人们在智能手机上常用的应用。

而对于消费应用来说,语言学习应用Duolingo是Swift的早期采用者,正利用Swift建立自己的Test Center应用。Lyft也是如此,正利用Swift开发其打车应用。流视频直播应用Meerkat同样是Swift的超级粉丝,该公司CEO本·鲁宾(Ben Rubin)表示:“我们喜欢Swift,我们知道它依然是一种新兴技术,有许多空白有待填补,为此我们期待其在开发体验方面的改进。”

但是有些网络评论家质疑称,Swift的存在可能是因为苹果正尝试为iPhone和iPad建立一种编程语言,令其应用更难用于安卓设备。但这可能只是部分原因。苹果精心塑造起公共形象,苹果工程师就像硅谷工程师一样,对解决问题感到兴奋不已,该公司的开发者们很可能抓住机会,向全球公布被他们视为更好的解决方案。

如果你依然习惯于使用Objective-C,苹果不会阻止你,它只是将Swift当作一种选择。为iPhone和Apple Watch开发健身应用的BodBot公司创始人塞尔吉奥·普拉多(Sergio Prado)说:“在文档中,他们平等对待Objective-C和Swift,他们从未想过使用Swift。”

这也就是说,BodBot的应用目前并未使用Swift,因为这不是他想要体验的。但普拉多说,他正关注着编程语言的发展。苹果有望在WWDC主题演讲中宣布Swift的更新方向。

谷歌语言Go前景不明

谷歌Go不像Swift那样呈现爆发式增长,这不仅仅是因为其针对更复杂、被称为“系统水平”的编程。Go项目描述自己为“由谷歌设计,帮助解决谷歌难题,谷歌有大问题。”你当然可以利用Go开发移动应用,但那并非其最擅长的领域。

热门应用容器引擎Docker、云托管服务平台DigitalOcean都在使用Go启动其内部项目。如果Swift是为开发iPhone应用而生,那么Go的使命就是帮助开发容纳应用数据的服务器应用。DigitalOcean软件工程师布莱恩·莱尔斯(Brian Liles)说:“在我们看来,Go很容易使用,为此我们将继续探索其可能性。”

但是总的来说,Go还没有成功起飞。帮助商家在云端开发应用的平台Apprenda战略研究部资深主管丹·特肯科普夫(Dan Turkenkopf)说:“到现在为止,我们还没有看到有太多企业客户使用Go,除了实验室的某些早期试验外。”

卡隆表示,主要原因是谷歌有很多悬而未决的编程项目。谷歌有Google Dart,这是另一种不太热门的编程语言。谷歌还在为安卓应用试验新的软件编译器,其代号为“Jack and Jill”,据说其有可能改变开发者开发应用的方式。换句话说,谷歌“空中有很多球”,开发者发现这些“球”的方向却都不同。

总之,谷歌与苹果都已经推出各自的编程语言,因为新技术的进步往往都是现有编程语言和技术存在不足所驱动。这也是他们推动自己议程的有趣方式之一,即使只为让更多人对谷歌和苹果正在做的事情发生兴趣。

但是正如卡隆指出的那样,更快、更少漏洞的代码不会自动让你的应用变得值得使用。像Swift和Go这样的编程语言并非“银弹”,即令应用变得更有用或使用起来更有趣。你同样需要更好的设计、更好的功能。

四 : 来自苹果的编程语言——Swift简介(1)

关于

这篇文章简要介绍了苹果于WWDC 2014发布的编程语言——Swift。

前言

在这里我认为有必要提一下Brec Victor的Inventing on Principle,Swift编程环境的大部分概念都源自于Brec这个演讲。

接下来进入正题。

来自苹果的编程语言——Swift简介(1)_swift是什么意思

Swift是什么?

Swift是苹果于WWDC 2014发布的编程语言,这里引用The Swift Programming Language的原话:

Swift is a new programming language for iOS and OS X apps that builds on the best of C and Objective-C, without the constraints of C compatibility. Swift adopts safe programming patterns and adds modern features to make programming easier, more flexible and more fun. Swift’s clean slate, backed by the mature and much-loved Cocoa and Cocoa Touch frameworks, is an opportunity to imagine how software development works. Swift is the first industrial-quality systems programming language that is as expressive and enjoyable as a scripting language.

简单的说:

  1. Swift用来写iOS和OS X程序。(估计也不会支持其它屌丝系统)
  2. Swift吸取了C和Objective-C的优点,且更加强大易用。
  3. Swift可以使用现有的Cocoa和Cocoa Touch框架。
  4. Swift兼具编译语言的高性能(Performance)和脚本语言的交互性(Interactive)。

Swift语言概览

基本概念

注:这一节的代码源自The Swift Programming Language中的A Swift Tour

Hello, world

类似于脚本语言,下面的代码即是一个完整的Swift程序。

  1. println("Hello,world")

变量与常量

Swift使用var声明变量,let声明常量

  1. varmyVariable=42
  2. myVariable=50
  3. letmyConstant=42

类型推导

Swift支持类型推导(Type Inference),所以上面的代码不需指定类型,如果需要指定类型:

  1. letexplicitDouble:Double=70

Swift不支持隐式类型转换(Implicitly casting),所以下面的代码需要显式类型转换(Explicitly casting):

  1. letlabel="Thewidthis"
  2. letwidth=94
  3. letwidth=label+String(width)

字符串格式化

Swift使用\(item)的形式进行字符串格式化:

  1. letapples=3
  2. letoranges=5
  3. letappleSummary="Ihave\(apples)apples."
  4. letappleSummary="Ihave\(apples+oranges)piecesoffruit."

数组和字典

Swift使用[]操作符声明数组(array)和字典(dictionary):

  1. varshoppingList=["catfish","water","tulips","bluepaint"]
  2. shoppingList[1]="bottleofwater"
  3. varoccupations=[
  4. "Malcolm":"Captain",
  5. "Kaylee":"Mechanic",
  6. ]
  7. occupations["Jayne"]="PublicRelations"

一般使用初始化器(initializer)语法创建空数组和空字典:

  1. letemptyArray=String[]()
  2. letemptyDictionary=Dictionary<String,Float>()

如果类型信息已知,则可以使用[]声明空数组,使用[:]声明空字典。

来自苹果的编程语言——Swift简介(1)_swift是什么意思

控制流

概览

Swift的条件语句包含ifswitch,循环语句包含for-inforwhiledo-while,循环/判断条件不需要括号,但循环/判断体(body)必需括号:

  1. letindividualScores=[75,43,103,87,12]
  2. varteamScore=0
  3. forscoreinindividualScores{
  4. ifscore>50{
  5. teamScore+=3
  6. }else{
  7. teamScore+=1
  8. }
  9. }
可空类型

结合iflet,可以方便的处理可空变量(nullable variable)。对于空值,需要在类型声明后添加?显式标明该类型可空。

  1. varoptionalString:String?="Hello"
  2. optionalString==nil
  3. varoptionalName:String?="JohnAppleseed"
  4. vargretting="Hello!"
  5. ifletname=optionalName{
  6. gretting="Hello,\(name)"
  7. }

灵活的switch

Swift中的switch支持各种各样的比较操作:

  1. letvegetable="redpepper"
  2. switchvegetable{
  3. case"celery":
  4. letvegetableComment="Addsomeraisinsandmakeantsonalog."
  5. case"cucumber","watercress":
  6. letvegetableComment="Thatwouldmakeagoodteasandwich."
  7. caseletxwherex.hasSuffix("pepper"):
  8. letvegetableComment="Isitaspicy\(x)?"
  9. default:
  10. letvegetableComment="Everythingtastesgoodinsoup."
  11. }

其它循环

for-in除了遍历数组也可以用来遍历字典:

  1. letinterestingNumbers=[
  2. "Prime":[2,3,5,7,11,13],
  3. "Fibonacci":[1,1,2,3,5,8],
  4. "Square":[1,4,9,16,25],
  5. ]
  6. varlargest=0
  7. for(kind,numbers)ininterestingNumbers{
  8. fornumberinnumbers{
  9. ifnumber>largest{
  10. largest=number
  11. }
  12. }
  13. }
  14. largest

while循环和do-while循环:

  1. varn=2
  2. whilen<100{
  3. n=n*2
  4. }
  5. n
  6. varm=2
  7. do{
  8. m=m*2
  9. }whilem<100
  10. m

Swift支持传统的for循环,此外也可以通过结合..(生成一个区间)和for-in实现同样的逻辑。

  1. varfirstForLoop=0
  2. foriin0..3{
  3. firstForLoop+=i
  4. }
  5. firstForLoop
  6. varsecondForLoop=0
  7. forvari=0;i<3;++i{
  8. secondForLoop+=1
  9. }
  10. secondForLoop

注意:Swift除了..还有.....生成前闭后开的区间,而...生成前闭后闭的区间。

函数和闭包

函数

Swift使用func关键字声明函数:

  1. funcgreet(name:String,day:String)->String{
  2. return"Hello\(name),todayis\(day)."
  3. }
  4. greet("Bob","Tuesday")

通过元组(Tuple)返回多个值:

  1. funcgetGasPrices()->(Double,Double,Double){
  2. return(3.59,3.69,3.79)
  3. }
  4. getGasPrices()

支持带有变长参数的函数:

  1. funcsumOf(numbers:Int...)->Int{
  2. varsum=0
  3. fornumberinnumbers{
  4. sum+=number
  5. }
  6. returnsum
  7. }
  8. sumOf()
  9. sumOf(42,597,12)

函数也可以嵌套函数:

  1. funcreturnFifteen()->Int{
  2. vary=10
  3. funcadd(){
  4. y+=5
  5. }
  6. add()
  7. returny
  8. }
  9. returnFifteen()

作为头等对象,函数既可以作为返回值,也可以作为参数传递:

  1. funcmakeIncrementer()->(Int->Int){
  2. funcaddOne(number:Int)->Int{
  3. return1+number
  4. }
  5. returnaddOne
  6. }
  7. varincrement=makeIncrementer()
  8. increment(7)
  1. funchasAnyMatches(list:Int[],condition:Int->Bool)->Bool{
  2. foriteminlist{
  3. ifcondition(item){
  4. returntrue
  5. }
  6. }
  7. returnfalse
  8. }
  9. funclessThanTen(number:Int)->Bool{
  10. returnnumber<10
  11. }
  12. varnumbers=[20,19,7,12]
  13. hasAnyMatches(numbers,lessThanTen)

闭包

本质来说,函数是特殊的闭包,Swift中可以利用{}声明匿名闭包:

  1. numbers.map({
  2. (number:Int)->Intin
  3. letresult=3*number
  4. returnresult
  5. })

当闭包的类型已知时,可以使用下面的简化写法:

  1. numbers.map({numberin3*number})

此外还可以通过参数的位置来使用参数,当函数最后一个参数是闭包时,可以使用下面的语法:

  1. sort([1,5,3,12,2]){$0>$1}

来自苹果的编程语言——Swift简介(1)_swift是什么意思

类和对象

创建和使用类

Swift使用class创建一个类,类可以包含字段和方法:

class Shape { var numberOfSides = 0 func simpleDescription() -> String { return "A shape with \(numberOfSides) sides." }}

创建Shape类的实例,并调用其字段和方法。

  1. varshape=Shape()
  2. shape.numberOfSides=7
  3. varshapeDescription=shape.simpleDescription()

通过init构建对象,既可以使用self显式引用成员字段(name),也可以隐式引用(numberOfSides)。

  1. classNamedShape{
  2. varnumberOfSides:Int=0
  3. varname:String
  4. init(name:String){
  5. self.name=name
  6. }
  7. funcsimpleDescription()->String{
  8. return"Ashapewith\(numberOfSides)sides."
  9. }
  10. }

使用deinit进行清理工作。

继承和多态

Swift支持继承和多态(override父类方法):

  1. classSquare:NamedShape{
  2. varsideLength:Double
  3. init(sideLength:Double,name:String){
  4. self.sideLength=sideLength
  5. super.init(name:name)
  6. numberOfSides=4
  7. }
  8. funcarea()->Double{
  9. returnsideLength*sideLength
  10. }
  11. overridefuncsimpleDescription()->String{
  12. return"Asquarewithsidesoflength\(sideLength)."
  13. }
  14. }
  15. lettest=Square(sideLength:5.2,name:"mytestsquare")
  16. test.area()
  17. test.simpleDescription()

注意:如果这里的simpleDescription方法没有被标识为override,则会引发编译错误。

属性

为了简化代码,Swift引入了属性(property),见下面的perimeter字段:

  1. classEquilateralTriangle:NamedShape{
  2. varsideLength:Double=0.0
  3. init(sideLength:Double,name:String){
  4. self.sideLength=sideLength
  5. super.init(name:name)
  6. numberOfSides=3
  7. }
  8. varperimeter:Double{
  9. get{
  10. return3.0*sideLength
  11. }
  12. set{
  13. sideLength=newValue/3.0
  14. }
  15. }
  16. overridefuncsimpleDescription()->String{
  17. return"Anequilateraltriaglewithsidesoflength\(sideLength)."
  18. }
  19. }
  20. vartriangle=EquilateralTriangle(sideLength:3.1,name:"atriangle")
  21. triangle.perimeter
  22. triangle.perimeter=9.9
  23. triangle.sideLength

注意:赋值器(setter)中,接收的值被自动命名为newValue

willSet和didSet

EquilateralTriangle的构造器进行了如下操作:

  1. 为子类型的属性赋值。
  2. 调用父类型的构造器。
  3. 修改父类型的属性。

如果不需要计算属性的值,但需要在赋值前后进行一些操作的话,使用willSetdidSet

  1. classTriangleAndSquare{
  2. vartriangle:EquilateralTriangle{
  3. willSet{
  4. square.sideLength=newValue.sideLength
  5. }
  6. }
  7. varsquare:Square{
  8. willSet{
  9. triangle.sideLength=newValue.sideLength
  10. }
  11. }
  12. init(size:Double,name:String){
  13. square=Square(sideLength:size,name:name)
  14. triangle=EquilateralTriangle(sideLength:size,name:name)
  15. }
  16. }
  17. vartriangleAndSquare=TriangleAndSquare(size:10,name:"anothertestshape")
  18. triangleAndSquare.square.sideLength
  19. triangleAndSquare.square=Square(sideLength:50,name:"largersquare")
  20. triangleAndSquare.triangle.sideLength

从而保证trianglesquare拥有相等的sideLength

调用方法

Swift中,函数的参数名称只能在函数内部使用,但方法的参数名称除了在内部使用外还可以在外部使用(第一个参数除外),例如:

  1. classCounter{
  2. varcount:Int=0
  3. funcincrementBy(amount:Int,numberOfTimestimes:Int){
  4. count+=amount*times
  5. }
  6. }
  7. varcounter=Counter()
  8. counter.incrementBy(2,numberOfTimes:7)

注意Swift支持为方法参数取别名:在上面的代码里,numberOfTimes面向外部,times面向内部。

?的另一种用途

使用可空值时,?可以出现在方法、属性或下标前面。如果?前的值为nil,那么?后面的表达式会被忽略,而原表达式直接返回nil,例如:

  1. letoptionalSquare:Square?=Square(sideLength:2.5,name:"optional
  2. square")
  3. letsideLength=optionalSquare?.sideLength

optionalSquarenil时,sideLength属性调用会被忽略。

枚举和结构

枚举

使用enum创建枚举——注意Swift的枚举可以关联方法:

  1. enumRank:Int{
  2. caseAce=1
  3. caseTwo,Three,Four,Five,Six,Seven,Eight,Nine,Ten
  4. caseJack,Queen,King
  5. funcsimpleDescription()->String{
  6. switchself{
  7. case.Ace:
  8. return"ace"
  9. case.Jack:
  10. return"jack"
  11. case.Queen:
  12. return"queen"
  13. case.King:
  14. return"king"
  15. default:
  16. returnString(self.toRaw())
  17. }
  18. }
  19. }
  20. letace=Rank.Ace
  21. letaceRawValue=ace.toRaw()

使用toRawfromRaw在原始(raw)数值和枚举值之间进行转换:

  1. ifletconvertedRank=Rank.fromRaw(3){
  2. letthreeDescription=convertedRank.simpleDescription()
  3. }

注意枚举中的成员值(member value)是实际的值(actual value),和原始值(raw value)没有必然关联。

一些情况下枚举不存在有意义的原始值,这时可以直接忽略原始值:

  1. enumSuit{
  2. caseSpades,Hearts,Diamonds,Clubs
  3. funcsimpleDescription()->String{
  4. switchself{
  5. case.Spades:
  6. return"spades"
  7. case.Hearts:
  8. return"hearts"
  9. case.Diamonds:
  10. return"diamonds"
  11. case.Clubs:
  12. return"clubs"
  13. }
  14. }
  15. }
  16. lethearts=Suit.Hearts
  17. letheartsDescription=hearts.simpleDescription()

除了可以关联方法,枚举还支持在其成员上关联值,同一枚举的不同成员可以有不同的关联的值:

  1. enumServerResponse{
  2. caseResult(String,String)
  3. caseError(String)
  4. }
  5. letsuccess=ServerResponse.Result("6:00am","8:09pm")
  6. letfailure=ServerResponse.Error("Outofcheese.")
  7. switchsuccess{
  8. caselet.Result(sunrise,sunset):
  9. letserverResponse="Sunriseisat\(sunrise)andsunsetisat\(sunset)."
  10. caselet.Error(error):
  11. letserverResponse="Failure...\(error)"
  12. }

结构

Swift使用struct关键字创建结构。结构支持构造器和方法这些类的特性。结构和类的最大区别在于:结构的实例按值传递(passed by value),而类的实例按引用传递(passed by reference)。

  1. structCard{
  2. varrank:Rank
  3. varsuit:Suit
  4. funcsimpleDescription()->String{
  5. return"The\(rank.simpleDescription())of\(suit.simpleDescription())"
  6. }
  7. }
  8. letthreeOfSpades=Card(rank:.Three,suit:.Spades)
  9. letthreeOfSpadesDescription=threeOfSpades.simpleDescription()

来自苹果的编程语言——Swift简介(1)_swift是什么意思

协议(protocol)和扩展(extension)

协议

Swift使用protocol定义协议:

  1. protocolExampleProtocol{
  2. varsimpleDescription:String{get}
  3. mutatingfuncadjust()
  4. }

类型、枚举和结构都可以实现(adopt)协议:

  1. classSimpleClass:ExampleProtocol{
  2. varsimpleDescription:String="Averysimpleclass."
  3. varanotherProperty:Int=69105
  4. funcadjust(){
  5. simpleDescription+="Now100%adjusted."
  6. }
  7. }
  8. vara=SimpleClass()
  9. a.adjust()
  10. letaDescription=a.simpleDescription
  11. structSimpleStructure:ExampleProtocol{
  12. varsimpleDescription:String="Asimplestructure"
  13. mutatingfuncadjust(){
  14. simpleDescription+="(adjusted)"
  15. }
  16. }
  17. varb=SimpleStructure()
  18. b.adjust()
  19. letbDescription=b.simpleDescription

扩展

扩展用于在已有的类型上增加新的功能(比如新的方法或属性),Swift使用extension声明扩展:

  1. extensionInt:ExampleProtocol{
  2. varsimpleDescription:String{
  3. return"Thenumber\(self)"
  4. }
  5. mutatingfuncadjust(){
  6. self+=42
  7. }
  8. }
  9. 7.simpleDescription

泛型(generics)

Swift使用<>来声明泛型函数或泛型类型:

  1. funcrepeat<ItemType>(item:ItemType,times:Int)->ItemType[]{
  2. varresult=ItemType[]()
  3. foriin0..times{
  4. result+=item
  5. }
  6. returnresult
  7. }
  8. repeat("knock",4)

Swift也支持在类、枚举和结构中使用泛型:

  1. //ReimplementtheSwiftstandardlibrary'soptionaltype
  2. enumOptionalValue<T>{
  3. caseNone
  4. caseSome(T)
  5. }
  6. varpossibleInteger:OptionalValue<Int>=.None
  7. possibleInteger=.Some(100)

有时需要对泛型做一些需求(requirements),比如需求某个泛型类型实现某个接口或继承自某个特定类型、两个泛型类型属于同一个类型等等,Swift通过where描述这些需求:

  1. funcanyCommonElements<T,UwhereT:Sequence,U:Sequence,T.GeneratorType.Element:Equatable,T.GeneratorType.Element==U.GeneratorType.Element>(lhs:T,rhs:U)->Bool{
  2. forlhsIteminlhs{
  3. forrhsIteminrhs{
  4. iflhsItem==rhsItem{
  5. returntrue
  6. }
  7. }
  8. }
  9. returnfalse
  10. }
  11. anyCommonElements([1,2,3],[3])

Swift语言概览就到这里,有兴趣的朋友请进一步阅读The Swift Programming Language。

接下来聊聊个人对Swift的一些感受。

个人感受

注意:下面的感受纯属个人意见,仅供参考。

大杂烩

尽管我接触Swift不足两小时,但很容易看出Swift吸收了大量其它编程语言中的元素,这些元素包括但不限于:

  1. 属性(Property)、可空值(Nullable type)语法和泛型(Generic Type)语法源自C#。
  2. 格式风格与Go相仿(没有句末的分号,判断条件不需要括号)。
  3. Python风格的当前实例引用语法(使用self)和列表字典声明语法。
  4. Haskell风格的区间声明语法(比如1..31...3)。
  5. 协议和扩展源自Objective-C(自家产品随便用)。
  6. 枚举类型很像Java(可以拥有成员或方法)。
  7. classstruct的概念和C#极其相似。

注意这里不是说Swift是抄袭——实际上编程语言能玩的花样基本就这些,况且Swift选的都是在我看来相当不错的特性。

而且,这个大杂烩有一个好处——就是任何其它编程语言的开发者都不会觉得Swift很陌生——这一点很重要。

拒绝隐式(Refuse implicity)

Swift去除了一些隐式操作,比如隐式类型转换和隐式方法重载这两个坑,干的漂亮。

Swift的应用方向

我认为Swift主要有下面这两个应用方向:

教育

我指的是编程教育。现有编程语言最大的问题就是交互性奇差,从而导致学习曲线陡峭。相信Swift及其交互性极强的编程环境能够打破这个局面,让更多的人——尤其是青少年,学会编程。

这里有必要再次提到Brec Victor的Inventing on Principle,看了这个视频你就会明白一个交互性强的编程环境能够带来什么。

应用开发

现有的iOS和OS X应用开发均使用Objective-C,而Objective-C是一门及其繁琐(verbose)且学习曲线比较陡峭的语言,如果Swift能够提供一个同现有Obj-C框架的简易互操作接口,我相信会有大量的程序员转投Swift;与此同时,Swift简易的语法也会带来相当数量的其它平台开发者。

总之,上一次某家大公司大张旗鼓的推出一门编程语言及其编程平台还是在2000年(微软推出C#),将近15年之后,苹果推出Swift——作为开发者,我很高兴能够见证一门编程语言的诞生。

本文来自:http://zh.lucida.me/blog/an-introduction-to-swift/

本文标题:苹果编程语言swift-苹果WWDC落幕 iOS 8新OS X及编程语言Swift亮相
本文地址: http://www.61k.com/1202689.html

61阅读| 精彩专题| 最新文章| 热门文章| 苏ICP备13036349号-1