這篇文章是想著幫助Android開發快速學習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>() |
Swift:
let
不能再次賦值. 如果物件型別是struct
, 不能更新物件的任何欄位. 如果是class
, 則仍可更新物件的var
欄位.var
可以給變數重新賦值, 也可以更新變數的var
欄位.var
可以宣告一個mutable的集合型別.Kotlin:
val
和java中的final
等價, 不能再給變數重新賦值, 但是仍然可以更新物件的var
欄位.var
意味著可以給變數重新賦值.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")
}
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)
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一樣), 如果你想在呼叫的時候省略, 可以用下劃線_
明確指明.
閉包和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")
相同點:
不同點:
return
關鍵字, 把表示式結果作為返回值. 而在Kotlin中, 最後的表示式值會被作為返回結果, 且在lambda中沒有return
關鍵字.$0
, $1
, $2
.Swift | Kotlin |
---|---|
class | class |
protocol | interface |
extension | extension methods |
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和class的區別:
deinit
.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類似Kotlin中的interface
.
我們可以定義一些方法或者計算屬性作為契約.
Properties寫起來是這樣的:
protocol SomeProtocol {
var mustBeSettable: Int { get set }
var doesNotNeedToBeSettable: Int { get }
}
protocol和interface有一點點小區別: 比如實現protocol的類的方法上不需要使用override
關鍵字.
在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()
}
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是一樣的.
雖然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
解包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的型別, 是一個確定有值的型別.
學習新的語言的時候, 不太建議花太多的時間鑽研語言的每個細節.
只需要瞭解一些最基本的知識, 然後就可以上手做具體的工作和任務.
在實際的任務中進行進一步的學習和練習.
總之, 希望這篇文章對你有用.