当前位置:网站首页>[Android開發學iOS系列] 語言篇: Swift vs Kotlin
[Android開發學iOS系列] 語言篇: Swift vs Kotlin
2022-07-21 02:36:00 【nginx】
這篇文章是想著幫助Android開發快速學習Swift編程語言用的. (因為這個文章的作者立場就是這樣.)
我不想寫一個非常長, 非常詳盡的文章, 只是想寫一個快速的版本能讓你快速上手工作.
當然這個文章可能也適合於以下人群:
- 有經驗的其他任何語言的開發者, 想學Swift.
- 一個會Swift的iOS開發者, 想橫向對比, 了解學習一下Kotlin.
- iOS初級程序員, 剛開始學習.
- 用過Swift, 但是有一陣子沒用了, 想快速刷新一下回憶.
SwiftKotlinBoolBooleanArrayArray, List, MutableListSetSetDictionaryMap其他基本類型都是差不多的.
語法
SwiftKotlin變量聲明let/varval/var具名參數at: 0at = 0函數/方法func name() → returnTypefun name(): returnType錶達無值nilnullunwrapped typeString!-ifif number != nilif(number != null)為空時提供默認值xxx ?? “default string”? : ”default string”不為空時做某件事if let number = Int(”333”) {}?.let {}for loopfor i in 1...5 {}for (i in 1..5) {}for loopfor i in 1..<5 {}for (i in 1 until 5) {}do while looprepeat {} whiledo {} while ()this instanceselfthisvalue objectstructdata classas?as?as!astry?-try!-class initializerinitializerconstructorinit a mutable listvar someInts: [Int] = []val someInts = mutableListOf()init a empty dictionary/mapvar namesOfIntegers: [Int: String] = [:]val namesOfIntegers = mutableMapOf<Int, String>() Constants and Variables
Swift:
- let 不能再次賦值. 如果對象類型是struct, 不能更新對象的任何字段. 如果是class, 則仍可更新對象的var字段.
- var 可以給變量重新賦值, 也可以更新變量的var字段.
- var 可以聲明一個mutable的集合類型.
- val和java中的final等價, 不能再給變量重新賦值, 但是仍然可以更新對象的var字段.
- var意味著可以給變量重新賦值.
- 集合類型的可變與否是被具體的集合類型聲明所决定的.
Swift:
Kotlin:
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")
}
String interpolation
val x = 3
when (x) {
1 -> print("x == 1")
2, 4 -> print("x == 2 or x == 4")
else -> print("x is something else")
}
Swift:
也可以給String規定格式:
var name = "Mike"
print("Hello \(name)")
Kotlin:
let str = NSString(format:"%d , %f, %ld, %@", 1, 1.5, 100, "Hello World")
print(str)
Function and Closure
var name = "Mike"
println("Hello $name")
val str = String.format("%d, %f, %d, %s", 1, 1.5, 100, "Hello World")
print(str)
Swift的function有一個argument label:
這裏parameterName是方法內部使用的, argumentLabel是被外部調用者使用的. (目的是為了增强可讀性.)
func someFunction(argumentLabel parameterName: Int) {
// In the function body, parameterName refers to the argument value
// for that parameter.
}
當argument label沒有提供的時候, parameter name同時也扮演argument label的角色.
在方法調用時argument label 默認是不能省略的(雖然有時候它和parameter name一樣), 如果你想在調用的時候省略, 可以用下劃線_明確指明.
Closure
閉包和Kotlin中的lambda相似.
一個簡單的Swift例子:
用Kotlin做同樣的事情:
let sayHello = { (name: String) -> String in
let result = "Hello \(name)"
print(result)
return result
}
sayHello("Mike")
相同點:
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.
SwiftKotlinclassclassprotocolinterfaceextensionextension methods class
Swift和Kotlin中的類定義和用法十分相似.
繼承是通過:符號, 子類可以override父類的方法.
繼承的的時候父類class需要放在protocol前.
只有構造看起來有點不同, 在Swift中叫initializer:
在Kotlin中, 可以通過如下的代碼達到相同的目的:
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)")
struct
class Person(val name: String = "") {
}
val p1 = Person()
print("${p1.name}") // default name: ""
val p2 = Person(name="haha")
print("${p2.name}")
struct是一個值類型.
struct和class的區別:
- class可以繼承.
- struct是值類型: 拷貝多份不會共享數據; class是引用類型, 所有的賦值拷貝最終都指向同一份數據實例.
- class有deinit.
- class的實例可以被let保存, 同時實例的var字段仍然可被修改, struct則不可修改.
這是ok的.
class Person {
var name = "Lily"
}
let p1 = Person()
p1.name = "Justin"
print("\(p1.name)")
如果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和interface有一點點小區別: 比如實現protocol的類的方法上不需要使用override關鍵字.
protocol SomeProtocol {
var mustBeSettable: Int { get set }
var doesNotNeedToBeSettable: Int { get }
}
extension
在Swift, extension更像是一個用來放擴展方法和屬性的地方.
在Kotlin中擴展方法可以是頂級方法, 只需要在.之前聲明類型:
extension String {
func trimmed() -> String {
self.trimmingCharacters(in: .whitespacesAndNewlines)
}
mutating func trim() {
self = self.trimmed()
}
var lines: [String] {
self.components(separatedBy: .newlines)
}
}
enum
fun String.someMethod() : String {
return this.trim()
}
Swift enum:
多個case也可以寫在一行, 用逗號分隔:
enum CompassPoint {
case north
case south
case east
case west
}
在Swift中使用枚舉的時候, 我們可以省略前面的類型, 只用一個.開頭:
enum Planet {
case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}
Swift enum有一個allCases屬性, 暴露所有case的集合.
var directionToHead = CompassPoint.west
directionToHead = .east
Kotlin:
在枚舉中我們也可以定義方法和屬性, 這個Swift和Kotlin是一樣的.
enum class Direction {
NORTH, SOUTH, WEST, EAST
}
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
注意當直接用的時候, 變量的類型永遠是Optional.
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
}
必須解包才能拿到值.
實際上在Swift中有一種更簡單的寫法來做這件事, 使用if let:
這裏someStringValue是從someString解包過的值, 後面的block只有當它不為nil時才會被執行.
if let someStringValue = someString {
print("\(someStringValue) with length \(someStringValue.count)")
}
在Kotlin中:
不同點主要在於有值的時候:
var someString : String? = null
print(someString?.length) // print null
print(someString!!.length) // NullPointerException
在Kotlin中, 如果我們判斷過變量不為null, 後面就可以直接用了, 編譯器知道這個變量現在不為空了.
var someString : String? = "Hello"
if(someString != null) {
print("$someString with length: ${someString.length}")
}
// print: Hello with length: 5
if let 和 guard let
我們上面的例子用if let解包Optional, 只在不為nil的時候執行大括號裏面的內容.
guard let做的事情正好相反: else block只在值為nil的時候才執行:
所以guard let通常被用來做參數檢測, 不合法就return.
func printSquare(of number: Int?){
guard let number = number else {
print("Oops we got nil")
return
}
print("\(number) * \(number) is \(number * number)")
}
並且在guard語句之後, number不再是一個optional的類型, 是一個確定有值的類型.
最後
學習新的語言的時候, 不太建議花太多的時間鑽研語言的每個細節.
只需要了解一些最基本的知識, 然後就可以上手做具體的工作和任務.
在實際的任務中進行進一步的學習和練習.
總之, 希望這篇文章對你有用.
References
- Swift book: https://docs.swift.org/swift-book/
作者: 聖騎士Wind
出處: 博客園: 聖騎士Wind
Github: https://github.com/mengdd
微信公眾號: 聖騎士Wind

边栏推荐
- 检查日期是否有效
- Alibaba cloud international account registration FAQ summary
- Reasons why loss does not decrease
- Introduction to target detection (up to 2020)
- 有奖调研 | 让虚拟照入现实的完美AR开发平台长什么样?
- MySQL 字段值里包含_和\转义符,如何在比对两个表的值时消除影响?
- 软件测试职业发展方向(不要迷茫了,赶紧卷起来)
- 【MUDUO 】Channel通道
- Calculate the date after adding the given number of working days
- Capacity scheduling absolute value configuration queue usage and pit avoidance
猜你喜欢
从0到1建设智能灰度数据体系:以vivo游戏中心为例
百度交易中台之钱包系统架构浅析
软件测试职业发展方向(不要迷茫了,赶紧卷起来)
Difi: a go as you pay Wi Fi access system intensive reading notes (III)
织梦添加栏目修改栏目时提示“保存目录数据时失败,请检查你的输入资料是否存在问题”
Metauniverse 3D wilderness
I have seven schemes to realize web real-time message push, seven!
一文详解|Go 分布式链路追踪实现原理
RESNET knowledge points supplement
excel数据条怎么设置百分比颜色?excel数据条按百分比自动填充颜色教程
随机推荐
Get the date of the year (number in the range 1-366) date from the object
A brief introduction to redis, the installation and configuration of redis source code, and the installation and mounting of docker
怎么批量删除Excel电子表格中不同的文字?
记录uni-app 打包成apk后获取定位
This beta version of Typora is expired,please download and install a newer version.
计算从今天开始的几天前的日期
Analysis on the wallet system architecture of Baidu trading platform
The difference between voice message and voice notification in okcc call center
HMS Core图形图像技术展现最新功能和应用场景,加速构建数智生活
Implementation principle of scala function & method and function & method
一文详解|Go 分布式链路追踪实现原理
Returns the quarter and year of the date provided
I have seven schemes to realize web real-time message push, seven!
软件界面和简单系统仿真
Batch gradient descent, random gradient descent and mini batch gradient descent
[Android开发学iOS系列] 语言篇: Swift vs Kotlin
NFT潮鞋AR互动零基础教程来啦!
【FAQ】接入HMS Core推送服务,服务端下发消息常见错误码原因分析及解决方法
[1000 cases of ArcGIS micro courses] 0029: ArcGIS drawing parallel lines (constructing parallel roads)
元宇宙 3D 开荒场