[Android開發學iOS系列] 語言篇: Swift vs Kotlin

来源:https://www.cnblogs.com/mengdd/archive/2022/07/19/swift-vs-kotlin.html
-Advertisement-
Play Games

這篇文章是想著幫助Android開發快速學習Swift編程語言用的. (因為這個文章的作者立場就是這樣.) 我不想寫一個非常長, 非常詳盡的文章, 只是想寫一個快速的版本能讓你快速上手工作. ...


Swift vs Kotlin

這篇文章是想著幫助Android開發快速學習Swift編程語言用的. (因為這個文章的作者立場就是這樣.)

我不想寫一個非常長, 非常詳盡的文章, 只是想寫一個快速的版本能讓你快速上手工作.

當然這個文章可能也適合於以下人群:

  • 有經驗的其他任何語言的開發者, 想學Swift.
  • 一個會Swift的iOS開發者, 想橫向對比, 瞭解學習一下Kotlin.
  • iOS初級程式員, 剛開始學習.
  • 用過Swift, 但是有一陣子沒用了, 想快速刷新一下回憶.

基本類型

Swift Kotlin
Bool Boolean
Array Array, List, MutableList
Set Set
Dictionary Map

其他基本類型都是差不多的.

語法

Swift Kotlin
變數聲明 let/var val/var
具名參數 at: 0 at = 0
函數/方法 func name() → returnType fun name(): returnType
表達無值 nil null
unwrapped type String! -
if if number != nil if(number != null)
為空時提供預設值 xxx ?? “default string” ? : ”default string”
不為空時做某件事 if let number = Int(”333”) {} ?.let {}
for loop for i in 1...5 {} for (i in 1..5) {}
for loop for i in 1..<5 {} for (i in 1 until 5) {}
do while loop repeat {} while do {} while ()
this instance self this
value object struct data class
as? as?
as! as
try? -
try! -
class initializer initializer constructor
init a mutable list var someInts: [Int] = [] val someInts = mutableListOf()
init a empty dictionary/map var namesOfIntegers: [Int: String] = [:] val namesOfIntegers = mutableMapOf<Int, String>()

Constants and Variables

Swift:

  • let 不能再次賦值. 如果對象類型是struct, 不能更新對象的任何欄位. 如果是class, 則仍可更新對象的var欄位.
  • var 可以給變數重新賦值, 也可以更新變數的var欄位.
  • var 可以聲明一個mutable的集合類型.

Kotlin:

  • val和java中的final等價, 不能再給變數重新賦值, 但是仍然可以更新對象的var欄位.
  • var意味著可以給變數重新賦值.
  • 集合類型的可變與否是被具體的集合類型聲明所決定的.

Switch case

Swift:

var x = 3
switch x {
    case 1: print("x == 1")
    case 2, 4: print("x == 2 or x == 4")
    default: print("x is something else")  
}

Kotlin:

val x = 3
when (x) {
    1 -> print("x == 1")
    2, 4 -> print("x == 2 or x == 4")
    else -> print("x is something else")
}

String interpolation

Swift:

var name = "Mike"
print("Hello \(name)")

也可以給String規定格式:

let str = NSString(format:"%d , %f, %ld, %@", 1, 1.5, 100, "Hello World")
print(str)

Kotlin:

var name = "Mike"
println("Hello $name")

val str = String.format("%d, %f, %d, %s", 1, 1.5, 100, "Hello World")
print(str)

Function and Closure

Swift的function有一個argument label:

func someFunction(argumentLabel parameterName: Int) {
    // In the function body, parameterName refers to the argument value
    // for that parameter.
}

這裡parameterName是方法內部使用的, argumentLabel是被外部調用者使用的. (目的是為了增強可讀性.)

當argument label沒有提供的時候, parameter name同時也扮演argument label的角色.

在方法調用時argument label 預設是不能省略的(雖然有時候它和parameter name一樣), 如果你想在調用的時候省略, 可以用下劃線_明確指明.

Closure

閉包和Kotlin中的lambda相似.

一個簡單的Swift例子:

let sayHello = { (name: String) -> String in
    let result = "Hello \(name)"
    print(result)
    return result
}

sayHello("Mike")

用Kotlin做同樣的事情:

val sayHello : (String) -> String = { name: String -> 
    val result = "Hello $name"
    print(result)
    result
}

sayHello("Mike")

相同點:

  • 可以根據上下文推斷類型, 所以有時候類型可以省略.
  • 可以作為另一個函數的參數傳入, 從而實現高階方法.
  • 如果閉包/lambda是方法的最後一個參數, 可以提到圓括弧外面. 如果是唯一的參數, 可以省略圓括弧.

不同點:

  • 在Swift中,只有單句表達式可以省略return關鍵字, 把表達式結果作為返回值. 而在Kotlin中, 最後的表達式值會被作為返回結果, 且在lambda中沒有return關鍵字.
  • Swift有縮略版本的參數名, 比如: $0, $1, $2.

Custom types

Swift Kotlin
class class
protocol interface
extension extension methods

class

Swift和Kotlin中的類定義和用法十分相似.

繼承是通過:符號, 子類可以override父類的方法.

繼承的的時候父類class需要放在protocol前.

只有構造看起來有點不同, 在Swift中叫initializer:

class Person {
    let name: String
    init(name: String = "") {
        self.name = name
    }
}
let p1 = Person()
print("\(p1.name)") // default name: ""

let p2 = Person(name: "haha")
print("\(p2.name)")

在Kotlin中, 可以通過如下的代碼達到相同的目的:

class Person(val name: String = "") {
}
val p1 = Person()
print("${p1.name}") // default name: ""

val p2 = Person(name="haha")
print("${p2.name}")

struct

struct是一個值類型.

struct和class的區別:

  • class可以繼承.
  • struct是值類型: 拷貝多份不會共用數據; class是引用類型, 所有的賦值拷貝最終都指向同一份數據實例.
  • class有deinit.
  • class的實例可以被let保存, 同時實例的var欄位仍然可被修改, struct則不可修改.
class Person {
    var name = "Lily"
}

let p1 = Person()
p1.name = "Justin"

print("\(p1.name)")

這是ok的.

如果Person是struct:

struct Person {
    var name = "Lily"
}

let p1 = Person()
p1.name = "Justin"
// Compiler error: Cannot assign to property: `p1` is a `let` constant

編譯器會報錯.

想要改變欄位值, 只能聲明: **var** p1 = Person().

protocol

protocol類似Kotlin中的interface.

我們可以定義一些方法或者計算屬性作為契約.

Properties寫起來是這樣的:

protocol SomeProtocol {
    var mustBeSettable: Int { get set }
    var doesNotNeedToBeSettable: Int { get }
}

protocol和interface有一點點小區別: 比如實現protocol的類的方法上不需要使用override關鍵字.

extension

在Swift, extension更像是一個用來放擴展方法和屬性的地方.

extension String {
    func trimmed() -> String {
        self.trimmingCharacters(in: .whitespacesAndNewlines)
    }
    
    mutating func trim() {
        self = self.trimmed()
    }
    
    var lines: [String] {
        self.components(separatedBy: .newlines)
    }
}

在Kotlin中擴展方法可以是頂級方法, 只需要在.之前聲明類型:

fun String.someMethod() : String {
    return this.trim()
}

enum

Swift enum:

enum CompassPoint {
    case north
    case south
    case east
    case west
}

多個case也可以寫在一行, 用逗號分隔:

enum Planet {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}

在Swift中使用枚舉的時候, 我們可以省略前面的類型, 只用一個.開頭:

var directionToHead = CompassPoint.west
directionToHead = .east

Swift enum有一個allCases屬性, 暴露所有case的集合.

Kotlin:

enum class Direction {
    NORTH, SOUTH, WEST, EAST
}

在枚舉中我們也可以定義方法和屬性, 這個Swift和Kotlin是一樣的.

Optionals

雖然Swift的optional type和Kotlin的nullable type看起來是類似的(都是具體類型後面加個問號), 但實際上它們還是有點不同.

Swift的optional type更像Java的Optional.

因為你在用之前永遠需要解包(unwrap).

var someString : String? = nil
print(someString?.count) // print nil
print(someString!.count) // Fatal error: Unexpectedly found nil while unwrapping an Optional value

當變數有值時, 我們需要用它:

var someString : String? = "Hello"

if (someString != nil) {
    print("\(someString) with length \(someString?.count)")
    // print: Optional("Hello") with length Optional(5)
    
    print("\(someString!) with length \(someString!.count)")
    // print: Hello with length 5
}

註意當直接用的時候, 變數的類型永遠是Optional.
必須解包才能拿到值.

實際上在Swift中有一種更簡單的寫法來做這件事, 使用if let:

if let someStringValue = someString {
    print("\(someStringValue) with length \(someStringValue.count)")
}

這裡someStringValue是從someString解包過的值, 後面的block只有當它不為nil時才會被執行.

在Kotlin中:

var someString : String? = null
print(someString?.length) // print null
print(someString!!.length) // NullPointerException

不同點主要在於有值的時候:

var someString : String? = "Hello"
if(someString != null) {
   print("$someString with length: ${someString.length}")  
}
// print: Hello with length: 5

在Kotlin中, 如果我們判斷過變數不為null, 後面就可以直接用了, 編譯器知道這個變數現在不為空了.

if let 和 guard let

我們上面的例子用if let解包Optional, 只在不為nil的時候執行大括弧裡面的內容.

guard let做的事情正好相反: else block只在值為nil的時候才執行:

func printSquare(of number: Int?){
    guard let number = number else {
        print("Oops we got nil")
        return
    }
    
    print("\(number) * \(number) is \(number * number)")
}

所以guard let通常被用來做參數檢測, 不合法就return.

並且在guard語句之後, number不再是一個optional的類型, 是一個確定有值的類型.

最後

學習新的語言的時候, 不太建議花太多的時間鑽研語言的每個細節.

只需要瞭解一些最基本的知識, 然後就可以上手做具體的工作和任務.
在實際的任務中進行進一步的學習和練習.

總之, 希望這篇文章對你有用.

References

作者: 聖騎士Wind
出處: 博客園: 聖騎士Wind
Github: https://github.com/mengdd
微信公眾號: 聖騎士Wind
微信公眾號: 聖騎士Wind
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 極品飛車14:熱力追蹤是一款非常有趣的競速賽車游戲,現為大家帶來的是內附完美存檔版,游戲將在全新的開放地圖中解鎖新的跑車及裝備,快來游戲中體驗賽車的樂趣吧,游戲非常炫酷,喜歡賽車游戲的朋友一定不要錯過! 詳情:極品飛車14:熱力追蹤 for Mac(競速賽車游戲)附完美存檔 游戲模式 生涯模式 《極 ...
  • 喜歡玩地鐵酷跑的玩家,可以試試這款Subway Surfers Tag Mac,又名地鐵衝浪,是一款頗受歡迎的休閑跑酷類游戲,您可以選擇在鐵路場、公園、碼頭和地下等挑戰酷跑衝浪,超炫酷,喜歡的朋友不要錯過哦~ 詳情:Subway Surfers Tag for mac(地鐵跑酷游戲) 游戲介紹 在鐵 ...
  • 鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站 源碼包編譯實例 下麵通過編譯安裝httpd來深入理解源碼包安裝(httpd-2.4.54) 下載編譯工具,httpd以及其兩個依賴包的源碼包 //源碼包建議到官方網站下載 [root@lnh ~]# mkdir xbz [root@lnh ~]# ...
  • 更多技術交流、求職機會、試用福利,歡迎關註位元組跳動數據平臺微信公眾號,回覆【1】進入官方交流群 需求背景 數據探查上線之前,數據驗證都是通過寫 SQL 方式進行查詢的,從編寫 SQL,到解析運行出結果,不僅時間長,還會反覆消耗計算資源,探查上線後,只需要一次探查,就可以得到整張表的探查報告,但後續我 ...
  • mysql 1.什麼是資料庫 資料庫:(DB,DataBase) 作用:用來存儲數據,管理數據。Txt,Excel,word是在資料庫出現之前存儲數據的。 概念:數據倉庫,安裝在操作系統上的軟體。 資料庫是所有軟體體系中最核心的存在 2.資料庫分類 關係型資料庫(SQL) Mysql,oracle, ...
  • #資料庫設計案例 ##描述:簡單構建設計資料庫 ##sql代碼實現 /* 資料庫設計案例 */ -- 音樂表 CREATE TABLE Music ( title VARCHAR (32), -- 專輯名 alias VARCHAR (32), -- 專輯別名 image VARCHAR (64), ...
  • 資料庫學習 1.簡單查詢 2022-07-13 測試腳本: drop TABLE emp;drop TABLE dept;drop TABLE salgrade;create table dept(deptno integer(4) not null,dname varchar(14),loc va ...
  • Fiddler5+雷電模擬器4對app抓包設置,棄用原來的老舊雷電3版本,保姆級教程小學生看了都說好。 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...