雜談Apple Swift

Apple的WWDC在昨天圓滿結束,指望iPhone6的同窗可能很失望,可是對於程序員們,他們又多了好多新玩具。除了成堆的新API,Apple還發布了一款全新的編程語言——Swifthtml

早就有謠言Apple會想辦法替換掉ObjectiveC,但你們都沒當回事。可此次,Apple直接放了大招。ios

並非Apple喜歡折騰,是ObjectiveC的確不招人喜歡:程序員

  1. 做爲一個C語言的變種,它有較爲陡峭的學習曲線
  2. 缺少動態特性。雖然新版的ObjectiveC已經很是努力的更新不少看起來很NB的東西,可是這在其餘語言確實天生支持的。

    1. Java直到8才支持lamda,但ObjectiveC的2013年就支持Block了。不過Block的限制太多,並且語法醜陋
    2. idinstancetype這些東西的產生都是很無奈的,無法完全解放複雜的類型申明
    3. 說好的generic和auto-boxing呢
    4. ...
  3. [[ObjectievC 的語法] 太羅嗦]
  4. ...(歡迎補充)

Swift發佈後,我第一時間下載了免費的教程,看完了Language Guide後寫下我第一篇關於Swift的文章。編程

能夠預料,網上已經有不少文章在說Swift又如何如何的好了。它到底好很差,咱們這打個問號。先讓說說它十分有特點的地方,順便附上免費吐槽。swift

Swift的產生

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編程指南中開篇的第一句話:數據結構

  1. 它是爲了編寫iOS和OSX的應用而產生的
  2. 它吸收了C和ObjectiveC的優勢
  3. 它去掉了爲了實現對C兼容性而作出的妥協

Swift的產生是面向將來的,而且是冷靜分析了當前Apple軟件生態圈以後概括總結出新語言。編程指南的開篇也提到,Apple內部已經使用了Swift多年。app

事實上,有LLVM在前,你們應該不難想像Apple能夠搞出不少種高級語言出來,反正只要能經過LLVM編譯,就能接入Apple的生態體系了。看看隔壁的微軟吧,一個.net上面有多少種語言?框架

Swift也不是Apple的第一次折騰。從Carbon到Cocoa,從MRC到ARC,你們都是含着淚走過來的。其實,Swift也並不能宣判ObjectiveC的死刑,我相信,對於這種翻天覆地的改動,就算一切順利,也須要一年左右的時間讓開發者接受。Apple極可能會觀察社區動向,同時對兩種語言進行調整,最壞的狀況下,有一部分市場的應用仍舊使用ObjectiveC,而另一部分,尤爲是遊戲,極可能完全拋棄ObjectiveC,而使用更敏捷的Swift。編程語言

Swift的定位,意味着它有豐富的動態特性,同時擁有靜態語言的性能和安全性。你能夠經過XCode6的Playground項目進行實驗,也能夠直接經過Swift編譯器進行調試。Swift Compiler位於:

/Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift

變量和數據類型

let it be

Swift的全部變量都須要用let或者var聲明。這兩個關鍵字的在別的語言普遍存在:ECMAScript(JavaScript、ActionScript)、Go。Swift也並不要求開發者必定須要寫明其數據類型,由於編譯器有必定能力推斷變量的數據類型。

let implicitInteger = 70
let implicitDouble = 70.0
let explicitDouble: Double = 70

注意,這並非說Swift變成弱類型了。事實上,Swift的變量一旦肯定了類型,便不能改變。並且,Swift也不存在隱式轉換。例如,若是須要字符串拼接,須要你手動轉換:

let widthLabel = label + String(width)

Generics

let emptyDictionary = Dictionary<String, Float>()

ObjectiveC的數據結構最大的詬病就是不支持Generic了。Swift還提供了兩個萬精油的數據類型:

  1. AnyObject
  2. Any

至關於於void*id了,這些東西聯合起來能夠說是讓你們對數據結構的應用更靈活一些了。

數據類型

除了常見的Int、UInt、Float、Double、Bool以外,它還有目前動態語言喜歡使用的Tuple。

var my2dPosition = (20, 20)
var my3dPosition = (20, 10, 50)

這也意味着,支持返回多個數值和Deconstructing了。

var (a,b) = (10,20)

而後就是Range,一種全閉合,一種半開半閉。

  • 1...3
  • 1..3

函數

好吧,Swift函數也很難看。它看起來像是Go、Ruby的結合體。但從特性上來說,Swift的函數是很是優秀的。

  • Functions are a first-class type
  • 可變的函數列表
  • Closure

    • 尾部Closure調用
    • 捕獲當前做用域
  • Local and external argument names

這部分將開來說太複雜了。能夠說該有的動態語言特性都有了。

流程控制

更嚴格的if語句在判斷條件時,並不考慮0,而只考慮Boolean。

功能無比強大的switch不再是雞肋了:

let somePoint = (1, 1)
switch somePoint {
case (0, 0):
    println("(0, 0) is at the origin")
case (_, 0):
    println("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
    println("(0, \(somePoint.1)) is on the y-axis")
case (-2...2, -2...2):
    println("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
    println("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}
// prints "(1, 1) is inside the box

enum、class、struct

enum放在這裏,是由於Swift裏面的enum的確都是一個類了。

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())
        }
    }
}

面對如此兇殘的enum咱們怎麼把持的住?

Swift的類繼承可能時Swift裏最接近C、C++的地方了。不管是它的默認構造函數、解構函數,仍是它後面提到的操做符重載都是C的那套思想,只是表現形式換了下。這意味着,這些東西很麻煩。

而同時又有動態語言常有的gettersetter那套。

struct Rect {
    var origin = Point()
    var size = Size()
    var center: Point {
    get {
        let centerX = origin.x + (size.width / 2)
        let centerY = origin.y + (size.height / 2)
        return Point(x: centerX, y: centerY)
    }
    set(newCenter) {
        origin.x = newCenter.x - (size.width / 2)
        origin.y = newCenter.y - (size.height / 2)
    }
  }
}

每一個Property還有兩個特殊的observer:

class StepCounter {
    var totalSteps: Int = 0 {
    willSet(newTotalSteps) {
        println("About to set totalSteps to \(newTotalSteps)")
    }
    didSet {
        if totalSteps > oldValue  {
            println("Added \(totalSteps - oldValue) steps")
        }
    }
    }
}

其餘的如ProtocolExtension什麼的依舊是有的,而且,二者均可以當作Type做爲聲明變量。

Optional Type

還不知道這個東西該怎麼翻譯成中文,直接上代碼吧:

if let johnsStreet = john.residence?.address?.street {
    println("John's street name is \(johnsStreet).")
} else {
    println("Unable to retrieve the address.")
}
// prints "Unable to retrieve the address."

一個值要麼存在,要麼爲nil。和if一塊兒使用被成爲Optional Binding

這恐怕是Swift裏最晦澀的概念了。因爲Swift裏沒有指針,而ObjectiveC裏一個默認行爲就是向nil對象的調用(發送消息)是沒有任何效果,這個特色要完整遷移到Swift裏是很困難的。Optional Type的確提供了這個可能, 但這也恐怕是Swift學習成本最大的地方了。

與Cocoa和CocoaTouch的混用

Swift能夠和Cocoa、CocoaTouch進行文件級別的混用,也就是說你的項目裏能夠同時存在這兩種文件。在Swift裏使用Cocoa的API也是能夠的:

let dataViewController = storyboard.instantiateViewControllerWithIdentifier("DataViewController") as DataViewController

Apple經過了複雜的橋接實現了這些,但能夠遠見以後會有很第三方多框架兼容性問題了。

Swift已經不支持C和C++代碼的混用了,要記住這是Swift產生的初衷之一。

指望和展望

我的預測它的流行程度很快會超過Go、Ruby,並與Python並排,以後會穩定上升,最終是否會超過ObjectiveC,甚至接近Java,都須要看Apple的佈局了。

XCode6內目前是支持以兩種不一樣的語言來編寫應用的,但不知道將來是否會慢慢淘汰ObjectiveC。Apple徹底有能力維護兩套語言,問題在於它是否須要。在不少領域,開發者早就渴望一種充滿動態語言特性的開發語言了,想一想iOS上那些內嵌Lua的應用吧。

可是,我以爲Swift並不應像它的前輩那樣停留在編寫幾個iOS或者Mac應用上面,它應該走出來,成爲真正意義上的通用語言。

相關文章
相關標籤/搜索