蘋果官方自己怎麼看待 Swift vs Objective-C
本文值得一讀,節錄一段如下:
實際上蘋果的團隊也很猶豫, 到底要繼續優化 Objective-C, 還是應該發明一門新的語言. 最後兩種方式都嘗試一下, 然後 Objective-C 就有了 ARC, 點語法等等新功能.
但最後, 蘋果的團隊發現 Objective-C 這門語言不安全最關鍵的原因還是因為它是基於 C 語言的, 它有指標, 它有不完全初始化的變數, 它會陣列越界. 即使蘋果的團隊對於工具鏈和編譯器有完整的控制權, 也沒辦法很好地解決這個問題.
蘋果的團隊想了又想, 反覆思慮之後, 還是決定打斷整個開發社群, 去建立一門 Safe的程式語言, 不只是那種沒有 bug的 Safe, 而是保持安全的同時還能提供高效能的, 推動整個程式設計正規化前進的那種 Safe.
Swift 與 Objective-C 並非是對立的, “Objective-C is Great”, Swift 只是蘋果提供的一個 “better option”.
如果從工程角度
1. 生態環境比語言成熟慢:Swift非常適合思考,但是目前還不是工程化 ready 的語言,主要是上下游生態環境還不成熟,需要時間。
2. 路徑依賴效應:人的路徑依賴無解;未來使用 Swift 並獲得巨大市場成功的公司,不是今天這些市場上的巨無霸;就像諾基亞比蘋果更早理解觸屏的價值,但仍然只能眼睜睜看著蘋果後來居上;普朗克曾經說過一句關於科學真理的真理,敘述為「一個新的科學真理取得勝利並不是通過讓它的反對者們信服並看到真理的光明,而是通過這些反對者們最終死去,熟悉它的新一代成長起來。」對於技術來說也是如此。
如果從語言技術角度
| oc | java | c# | c++ | swift | python | |
| 值物件 | 有 | 沒有 | 沒有 | 有 | 有 | 有 |
| 指標(缺陷) | 有 | 沒有 | 沒有 | 有 | 沒有 | 沒有 |
| 記憶體管理 | 引用計數 | 垃圾回收 | 垃圾回收 | 智慧指標(缺陷) | 引用計數 | 垃圾回收 |
| 多返回值 | 沒有 | 沒有 | 沒有 | 沒有 | 有 | 有 |
| 指令碼語言特性 | 沒有 | 沒有 | 沒有 | 沒有 | 有 | 有 |
| 移動端支援 | ios | android | 遊戲 | 遊戲 | ios | 較少(缺陷) |
D 與 Rust 適合於那些長期使用 C++ 並且已經適應了要去掌握超多語法與概念的人,但是想要使用些更加清晰明瞭與安全的語言。這型別的開發者往往從事著類似於遊戲引擎、編譯器、加解密庫、HTML渲染引擎等等類似的工作。
Swift 呢,更多意義上是一門面向於應用程式設計的語言,它很容易上手,在某些方面它應該與 Go、Java、Python 以及 C# 相提並論。不過 Swift 會比這些更容易開始學習,它的helloworld 只需要一行程式碼就好了,並且它是支援函式的(不像 Java 那樣完全的 OO)。你不需要學習任何的類與物件的知識就可以開始撰寫簡易的 Swift 的程式碼。基於此,Swift 是更合適用作一種教學語言的,它還有像指令碼語言一樣的互動環境,也就是 REPL 以及 Xcode 本身提供的 PlayGround。
綜上所述,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 具有良好的記憶體使用的策略和結構。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 中經常會看到 ! 與 ? 兩個操作符,譬如在型別轉換、可選型別構造中都用到,用 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,你幫我查查有沒有進行完備的空檢查。
《Swift 編程語言》是蘋果官方對 Swift 語言所做的權威指南,很遺憾蘋果公司並沒有進行多語言支持。所以某位用戶獨立發起了這個手冊的翻譯工作——與其他現存翻譯不同的是:它同步更新蘋果官方的 Swift 開發者預覽版 !
也就是說:一旦官方文檔更新,會立即進行同步:
https://www.cnswift.org/
手機 App 開發與接案 - 總覽:http://21st.each1.net/2018/04/app.html
Swift 是蘋果在 WWDC2014 發表的一門程式設計語言,用來撰寫 OS X 和 iOS 應用程式。
對於已經掌握一兩門程式設計語言的程式師來說,他的選擇要取決於「已有的一兩種語言」是什麼。如果這兩種語言是 Objective-C 和 Swift,或者 C 和 C++,或者其中任何組合,為了挑戰思惟,他可以去學習一種完全不同的語言,比如一種函數式語言(舉例:Scheme)。
C、C++、Objective-C 以及 Swift 這樣的命令式語言都遵循著相同的模型,學習同類語言很簡單,因此就需要讓自己多接觸不同的語言泛型。雖然他可能並不會用這種語言來寫應用,但這會有利於全面開啟他對於電腦語言的理解。
長達600多頁的 The Swift Programming Language 可以在 iBooks 免費下載。
維基百科關於 Swift 的資料:
https://en.wikipedia.org/wiki/Swift_(programming_language)
所有電腦語言都會從其他語言身上借鑒一些東西。對於 Swift 來說也是如此。從語法和儲存模型的角度上說,Swift 就有很多 Rust 的影子。此外,Swift 對於安全的強調使其與 C 和 C++ 保持了一定距離,所以它們之間的共同點比較少。
Swift 取消了 Objective-C 的指標及其他不安全存取的使用,並捨棄 Objective-C 早期套用 Smalltalk 之語法,全面改為句點表示法(dot-notation)。同許多手稿語言一樣,Swift 可以推斷變數型別(var, variant)。同時,它提供了類似 C++、C# 的命名空間(namespace)、泛型(generic)、運算元重載(operator overloading)。Swift 被簡單形容為 「沒有 C 的 Objective-C」(Objective-C without the C)。
蘋果在新網站 swift.org 和託管網站 Github 上開源了 Swift,並支援 Linux,但蘋果的 app store 並不支援開源的 Swift,只支援蘋果官方的 Swift 版本,官方版本會在新網站 swift.org 上定期與開源版本同步。
蘋果開源 Swift 的目標顯然是想讓 Swift 在幾年後成為 iOS 的主流程式語言甚至慢慢地成為軟體開發界的主流語言,跨越到『非蘋果』的平台。
有必要掌握所有 API 嗎?
關於何時接觸大量的庫和 API,以及是否需要學習所有 API ,結論當然是否,好比一個木匠的工具腰帶中只會裝上那些經常使用的工具。當他需要特殊工具的時候,他會來到庫房,打開裡面的大工具箱,把需要的特殊工具找出來使用,然後再把它放回去。而這種使用頻率往往在很長一段時間裡也只有一次到兩次。雖然知道的 API 越多,就越能更好地解決問題,但是有多少人能完整地瞭解所有 API 呢?先比較完整地學習一門語言,然後再繼續研究這種語言的細微之處,也就是開始接觸這門語言中可以用來創建有用應用的框架和 API。然後可以按照一定頻率(比如每週一次,每次 3-5 小時)去選擇一個新的 API 來學習它的功能。可能並不會經常使用這個 API,但是瞭解它,當需要用到時,就會知道「從哪裡把它取出來使用」。
一個全面的 iOS 專家必須掌握這四樣東西:
1. 用來寫應用的語言:Swift。
2. 熟悉創建軟體的工具:Xcode。
3. 儲備大量關於 iOS 應用基礎框架和 API (函式庫)。
4. 鑒別好的 UI 設計的能力。
可能要經歷很多應用程式和上百小時的程式設計才能達到這個水準,每個應用都有自身的要求和需要的 API。只要寫的應用程式越多,就能越廣地接觸到各式蘋果框架,UI 設計技巧也會越來越好。
初學者的十個 iOS App 開發 Q & A:
https://blog.alphacamp.co/2016/05/11/10-questions-you-need-to-know-before-ios-app-development/
Swift 是 Apple 精心培育的新世代程式語言,有許多精巧的設計蘊含其中。這些設計一方面讓 Swift 成為更優秀的語言,一方面卻也讓 Swift 自學者困惑不已。
最人盡皆知的大概就是 optional variable 了。雖然掌握 optional 的精神後會覺得 optional 是超精心的巧思,但第一次接觸 Swift 的人,大概會被程式碼中滿滿的問號與驚嘆號嚇傻。
所幸,關於這個人盡皆知的議題,AppCoda 已經寫了一篇《初學Swift:愛恨交織的 Optional》在《邂逅Swift你需要知道的 n 件事》一書中充分討論。
邂逅Swift你需要知道的 n 件事:https://legacy.gitbook.com/book/gradyzhuo/meetswifttutorial/details
如何理解 if let 與 guard: https://21st.each1.net/2018/08/swift-if-let-guard.html
線上教學:
https://www.hackingwithswift.com
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID309
https://itisjoe.gitbooks.io/swiftgo/
http://www.runoob.com/swift/swift-tutorial.html
https://www.appcoda.com.tw
從專案範例來學習使用 Xcode:
https://www.appcoda.com.tw/hello-world-app-swift/
https://www.hackingwithswift.com/read
電子書:https://medium.com/彼得潘的-swift-ios-app-開發教室/xcode-嘗試做一個實用的app吧-d5103ee1ae5d
How to create live playgrounds in Xcode:
https://www.hackingwithswift.com/example-code/uikit/how-to-create-live-playgrounds-in-xcode
Struct or Class?
https://tw.alphacamp.co/2016/07/20/swift-struct-or-class/
Apple 早期的 Swift 文件推薦開發者優先使用 class;一些近期的文件則推薦優先使用 struct。
在其他有 struct 的語言中, struct 一般只能拿來組織邏輯相關的 data,使用上沒什麼疑義。但在 Swift 中,struct 除了可以整理相關的資料,還擁有 initializer、擁有 method ,除了無法被繼承以外,和 class 的使用方式幾乎完全一樣。這就衍生了另一個問題:在不需要繼承的情況下,到底該用 struct 還是 class?
在討論這個議題前,我們需要知道一些底層的知識。
記憶體分成 heap 和 stack 兩塊。class 物件是 reference type,會被儲存在 heap ; struct 物件是 value type,會被存在 stack。一般而言, stack 的執行效率會比 heap 好,所以一模一樣的事情,交給 struct 做,理論上會比 class 有效率(根據國外網友實測,越新版的 Swift,struct 效能較強這件事越顯著)。
不過「寫出好讀、好維護的程式碼」大部分的時候比「寫出高效能的程式碼」重要。 struct 執行效率較高絕對不是 Apple 在新文件中推廣 struct 的原因。
Object-Oriented Programming (OOP) 是近年軟體開發的主流設計模式,但在 2015 WWDC,Apple 對這個稱霸數十載的設計模式提出挑戰。
Apple 認為,在 OOP 的架構中,假如 super class 定義過於狹窄,能繼承於此 super class 的 sub class 就會較少;為了讓 super class 較「通用」、能被較多 sub classes 繼承,開發者往往需要在 super class 中加入許多 properties,但這些 properties 卻未必是每個 sub class 都需要的。於是,OOP 為主的專案容易龐雜、且程式碼容易缺乏彈性。
於是,Apple 提出 Protocol Oriented Programming(POP),主張應該用 protocol 當作設計程式架構的基礎,以解決 OOP 容易龐雜、缺乏彈性的缺點。
對 POP 細節有興趣的讀者可以自行觀看 WWDC 影片。總之,class 能夠被繼承的特性是 OOP 的核心,但 class 有效率較差、資料容易被誤改(因為 reference type 的特性)的問題。假如改用 OOP 以外的設計模式(例如POP),我們就不必常常依賴 class 的繼承特性,自然就可以優先使用效率較佳、資料較「安全」(因為 value type 的特性)的 struct。
class 和 struct 在 Swift 中非常相似,傳統上,我們習慣使用 OOP,所以會優先(且「必須」)使用 class。但自從 Apple 開始推廣 POP,在這個新的設計模式下,我們對 class 能夠繼承的特性不再那麼倚賴,所以在大部分的情境下,使用優點較多的 struct 就變比較合理的選擇。
不過 OOP 畢竟還是當前主流,Apple 自己也說 OOP 還是有優點和必要, POP 無法完全取代 OOP。
到底要用 class 還 struct ,仍需要根據個別情況斟酌。
可以確定的是,在 swift 中,稱霸數十載的 class 不再是需要使用物件時的唯一選擇了。