我把自己學習Swift語法的筆記通過4篇左右的文章分享給大家。由于是個人筆記,代碼較多,配的文字很少,對于Swift初學者的理解可能會造成一些困難。
我會在《Swift語法學習筆記》系列中覆蓋以下內容:
- Swift常量與變量
- Swift常用數(shù)據(jù)類型
- 基本數(shù)據(jù)類型
- 集合類型
- 可選類型
- 流程控制
- if語句
- for循環(huán)
- while語句
- repeat語句
- Switch語句
- 函數(shù)和閉包
- 函數(shù)
- 閉包
- 結構體
- 定義與使用結構體
- 結構體的初始化方法
- 類
- 類
- 繼承
本篇是《Swift語法學習筆記》系列的第一篇文章,將涵蓋以下內容:
- Swift常量與變量
- Swift常用數(shù)據(jù)類型
- 基本數(shù)據(jù)類型
- 整型
- 字符串類型
- 布爾類型
- 枚舉類型
- 集合類型
- 數(shù)組
- 字典
- Sets
- NSArray、NSDictionary、NSSet
- 可選類型
- Swift鄭家可選類型的原因
- 獲取可選類型的真實值
- 獲取字典中不存在的默認值
- 枚舉類型中的可選類型
- as與as!的區(qū)別
- as?
- 基本數(shù)據(jù)類型
1 常量與變量
1.1 常量
Swift使用let聲明常量,必須在聲明的同時進行初始化賦值,且其值不可更改。
1.2 變量
Swift使用var聲明變量:
var str = "Hello World!" //Swift會自動推定str的類型為String,編譯器一旦完成類型推定,此后的代碼均不可以修改變量的類型
或者
var str : String
str = "Hello World"
2 數(shù)據(jù)類型
2.1 基本數(shù)據(jù)類型
2.1.1 Int整型
獲取Int數(shù)據(jù)類型的最小值與最大值:
Int8.min
Int8.max
UInt32.min
UInt32.max
各種進制的表示方法:
let decimal = 123 // Value is 123
let octal = 0o77 // Octal 77 = decimal 63
let hex = 0x1234 // Hex 1234 = decimal 4660
let binary = 0b1010 // Binary 1010 = decimal 10
為了更好的可讀性,在賦值時可以使用“_”分隔數(shù)字:
let v = -1_234 // Same as -1234
let w = 12_34_56 // Same as 123456
聲明常量的同時指定數(shù)據(jù)類型:
let a = 1.23 // This is inferred to be a Double
let b: Float = 1.23 // Forced to be Float
Swift不可以做如下形式的類型推定:
let a = 123
let b = 0.456
let c = a + b //由于a為Int類型,b為Double類型,所以編譯器不能決定c到底是什么類型
若要成功編譯,需要將a轉換為Double類型
let a = 123
let b = 0.456
let c = Double(a) + b
2.1.2 String類型
使用轉譯符“\”在字符串中插入雙引號:
let quoted = "Contains \"quotes\"" // Contains "quotes"
插入反斜杠:
let backslash = "\\" // Result is \
插入換行符與縮進符:
let specialChars = "Line1\nLine2\tTabbed"
插入數(shù)值:
print("The value of pi is \(M_PI)") // Prints "The value of pi is 3.14159265358979\n"
插入表達式:
// This code prints: "Area of a circle of radius 3.0 is 28.2743338823081\n"
let r = 3.0
print("Area of a circle of radius \(r) is \(M_PI * r * r)")
字符串相加:
let s = "That's one small step for man, " + "one giant leap for mankind"
print(s) // "That's one small step for man, one giant leap for mankind\n"
比較字符串:
let s1 = "String one"
let s2 = "String two"
let s3 = "String " + "one"
s1 == s2 // false: strings are not the same
s1 != s2 // true: strings are different
s1 == s3 // true: strings contain the same characters.
獲取字符串的長度:
s3.characters.count // 10
s3.utf16.count // 10
字符類型只能包含一個字符,且必須用雙引號包圍。
let c: Character = "s"
不能使用“+”運算符將字符串與字符相加,需要使用字符串的append方法:
let c: Character = "s"
var s = "Book" // "var" because we want to modify it
s += c // Error – illegal
s.append(c) // "Books"
Swift中的字符串等簡單數(shù)據(jù)類型都是“拷貝類型”(只有類除外,類是“引用類型”):
var s1 = "Book"
var s2 = s1 // s2 is now a copy of s1
s2 += "s" // Appends to s2; s1 is unchanged
s1 // "Book"
s2 // "Books"
2.1.3 Bool類型
var b = true // Inferred type is Bool
var b1: Bool
b1 = false
2.1.4 enum枚舉類型
定義枚舉類型:
enum DaysOfWeek {
case Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
}
或者
enum DaysOfWeek {
case Sunday
case Monday
case Tuesday
case Wednesday
case Thursday
case Friday
case Saturday
}
var day = DaysOfWeek.Sunday // "day" is inferred to be of type "DaysOfWeek"
day = .Friday // Note that the "." Is required
包含其他數(shù)據(jù)類型的枚舉:
enum Status {
case OK
case ERROR(String)
}
let status = Status.OK
let failed = Status.ERROR("That does not compute") //這里的failed被推定為什么類型?
含有原始值的枚舉:
enum DaysOfWeek : Int {
case Sunday = 0 // 0
case Monday // 1
case Tuesday // 2
case Wednesday // 3
case Thursday // 4
case Friday // 5
case Saturday // 6
}
或者
enum DaysOfWeek : Int {
case Sunday = 0
case Monday // 1
case Tuesday // 2
case Wednesday // 3
case Thursday // 4
case Friday = 20 // 20
case Saturday // 21
}
var day = DaysOfWeek.Saturday
let rawValue = day.rawValue // 21 rawValue位Int類型
原始值為字符串的枚舉:
enum ResultType : String {
case SUCCESS = "Success"
case WARNING = "Warning"
case ERROR = "Error"
}
let s = ResultType.WARNING.rawValue // s = "Warning"為String類型
通過指定枚舉類型的原始值可以獲取對應的“枚舉值”:
let result = ResultType(rawValue: "Error") // 返回ERROR,result的類型為ResultType?可選類型,具體可以參照“3 可選類型”
2.2 集合類型
2.2.1 數(shù)組
聲明數(shù)組:
var integers = [1, 2, 3]
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
或者
var integers: [Int] // [Int] means "array of Ints"
integers = [1, 2, 3]
空數(shù)組
var empty: [String] = []
數(shù)組的索引范圍:
var integers = [1, 2, 3]
integers[1..<3] // Get elements 1 and 2 as an array. Result is [2, 3]
integers[1..<3] = [4] // Replace elements 1 and 2 with [4]. Result is [1, 4]
integers = [1, 2, 3]
integers[0...1] = [5, 4] // Replace elements 0 and 1 with [5, 4]. Result is [5, 4, 3]
增加新元素:
var integers = [1, 2, 3]
integers.append(4) // Result is [1, 2, 3, 4]
或者
integers.insert(-1, atIndex: 0) // Result is [-1, 1, 2, 3, 4]
或者
var integers = [1, 2, 3]
let a = integers + [4, 5] // a = [1, 2, 3, 4, 5]; integers array unchanged
integers += [4, 5] // Now integers = [1, 2, 3, 4, 5]
刪除元素:
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
days.removeAtIndex(3) // Removes "Wednesday" and returns it to the caller
days.removeRange(0..<4) // Leaves ["Friday", "Saturday"]
days.removeAll(keepCapacity: false) // Leaves an empty array
常量數(shù)組一旦初始化,不可更改其值:
let integers = [1, 2, 3] // Constant array
integers = [4, 5, 6] // Error: cannot replace the array
integers[0] = 2 // Error: cannot reassign elements
integers.removeAll(keepCapacity: false) // Error: cannot modify content
驗證復制特性:
var integers = [1, 2, 3]
var integersCopy = integers // Creates a copy of "integers"
integersCopy[0] = 4 // Does not change "integers"
integers // [1, 2, 3]
integersCopy // [4, 2, 3]
檢查數(shù)組中是否存在某個值:
let integers = [1, 2, 3]
integers.contains(2) // true
integers.contains(4) // false
獲取數(shù)組中某個值的索引值:
let integers = [1, 2, 3]
let index = indexOf(3)!.value // Result is 2
2.2.2 字典
聲明一個類型為[String, Int](<String, Int>)的字典:
var dict = ["Red": 0,
"Green": 1,
"Blue": 2]
或者
var dict: [String: Int]
dict = ["Red": 0, "Green": 1, "Blue": 2]
獲取字典值:
let value = dict["Red"] // Result is 0, the value mapped to the key "Red"
獲取字典的鍵值對總數(shù):
var dict = ["Red": 0, "Green": 1, "Blue": 2]
dict.count // 3
修改字典值:
dict["Yellow"] = 3 // Adds a new value with key Yellow
dict["Red"] = 4 // Updates the value with key Red
刪除字典值:
var dict = ["Red": 0, "Green": 1, "Blue": 2]
dict.removeValueForKey("Red") // Removes value with key "Red"
dict.removeAll() // Empties the dictionary
常量字典不能修改:
let fixedDict = ["Red": 0, "Green": 1, "Blue": 2]
fixedDict["Yellow"] = 3 // Illegal
fixedDict["Red"] = 4 // Illegal
fixedDict = ["Blue", 7] // Illegal
fixedDict.removeValueForKey["Red"] // Illegal
2.2.3 集合Sets(無序數(shù)組)
聲明Set:
let s1 = Set([1, 2, 3])
或者
let s2: Set<Int> = [1, 2, 3]
是否含有某元素:
s1.contains(1) // true
s2.contains(4) // false
s1.count // 3
增加元素:
var s1 = Set([1, 2, 3]) // [2, 3, 1] (note that order does not matter in a set)
s1.insert(4) // [2, 3, 1, 4]
刪除元素:
s1.remove(1) // [2, 3, 4]
s1.removeAll() // [] (empty set)
2.2.4 NSArray, NSDictionary and NSSet
聲明一個NSString:
let s: NSString = "Red,Green,Blue"
使用NSString:
let s: NSString = "Red,Green,Blue"
let components = s.componentsSeparatedByString(",") // Calls the NSString method
components //[String]類型的["Red", "Green", "Blue"]
使用NSDictionary:
let d = NSDictionary()
強制轉換
let e = d as Dictionary
或者
let d = NSDictionary()
let e = d as! [String: String]
2.3 可選類型
2.3.1 Swift增加可選類型的原因
var dict: [String: Int];
dict = ["Red": 0, "Green": 1, "Blue": 2]
let value = dict["Red"] //the inferred type for value is not Int, but Int?—an optional integer
Swift中為什么會增加可選類型呢?考慮這種情況:
let yellowValue = dict["Yellow"]
What value should be assigned to yellowValue? Most languages address this by having a distinguished value that means, by convention, “no value.” In Objective-C, this value is referred to as nil (which is really just a redefinition of 0); in C and C++ it’s NULL (again, a redefinition of 0); and in Java it’s null.
The problem with this is that it can be dangerous to use a nil (or equivalent) value. In Java, for example, using a null reference causes an exception; in C and C++, the application is likely to crash.What's worse, there's no way to know from its declaration whether a variable might contain a null (or nil or NULL) value.
Swift solves this problem in a neat way: it has a nil value, but a variable (or constant) can only be set to nil if it's declared as an optional, or its type is inferred to be optional. As a result, you can tell immediately whether a variable or constant could be nil by examining its type: if it's not optional, it can't be nil. Further to that, Swift requires you to take that into account explicitly whenever you use the value.
不能賦值nil給非可選類型賦值nil:
var color = "Red"
color = nil // Illegal: color is not an optional type.
不能賦值可選類型給非可選類型:
let dict = [0: "Red", 1: "Green", 2: "Blue"]
color = dict[0] // Illegal: value of dict[0] is optional string, color is not optional.
可以將可選類型賦值給可選類型(或者未初始化的常量與變量):
let dict = [0: "Red", 1: "Green", 2: "Blue"]
var color: String? // "String?" means optional String,color的值為nil
color = dict[0] // Legal
print(color) // printed is not“Red” but Optional("Red"),這其實是一個裝箱(wrapped)后的值
2.3.2 獲取可選類型的值
為了得到可選類型的實際值,需要對可選類型進行Unwrap(拆箱)操作:
let actualColor = color! // "color!" means unwrap the optional, actualColor是String類型
上面的操作其實可以理解為強制拆箱操作,不論其值是否真的存在,這么做其實是很危險的。試看以下操作:
let dict = [0: "Red", 1: "Green", 2: "Blue"]
let color = dict[4] //color是String?類型,其值為nil
let actualColor = color! //對值nil的可選類型進行拆箱,會造成程序崩潰
為了避免發(fā)程序崩潰,需要對可選類型進行安全檢查:
if color != nil {
let actualColor = color!
}
或者
if let actualColor = color {
// Executed only if color was not nil
print(actualColor)
}
或者
if var actualColor = color {
// Executed only if color was not nil. actualColor can be modified
print(actualColor)
}
或者
if var color = color {
// Executed only if the value of the original color variable was not nil
print(color) // Refers to the new variable, holding the unwrapped value
}
或者
let dict = [0: "Red", 1: "Green", 2: "Blue"]
let color = dict[0]
if var color = color {
// Executed only if color was not nil
print(color) // "Red"
color = "Green" // Reassigns the local variable
} // New color variable is now out of scope
color // Refers to the original value: "Red"
2.3.3 獲取字典中不存在的默認值
let dict = [0: "Red", 1: "Green", 2: "Blue"]
let color = dict[4]
let actualColor = color ?? "Blue"
或者
let dict = [0: "Red", 1: "Green", 2: "Blue"]
let actualColor = dict[4] ?? "Blue"
2.3.4 枚舉類型中的可選類型
enum ResultType : String {
case SUCCESS = "Success"
case WARNING = "Warning"
case ERROR = "Error"
}
let result = ResultType(rawValue: "Invalid") //result為ResultType?類型,其值為nil
!可選類型的作用:
let dict = [0: "Red", 1: "Green", 2: "Blue"]
var color: String! // Notice the !,這個操作告訴編譯器color永遠不可能為 nil值
color = dict[0] // Assigns Optional("Red")
print(color) // Automatically unwraps the optional
2.3.5 as與as!的區(qū)別
Roughly speaking, you use as when the cast is guaranteed to work and as! when it’s not—the ! expresses the fact that you are forcing the compiler to accept code that it would otherwise report an error for, such as when downcasting.
as可以用于子類向父類的轉換:
let s = "Fred"
let n = s as NSString
或者
let label = UILabel()
let view = label as UIView
as!用于父類向子類的強制轉換,或未知類向任意類的轉換:
let view: UIView = UILabel()
let label = view as! UILabel // Downcast requires !
或者
let d = NSDictionary(objects: ["Red", "Green", "Blue"], forKeys: [0, 1, 2])
let color = d[1] as! String
2.3.6 as?
let d = NSDictionary(objects: ["Red", "Green", "Blue"], forKeys: [0, 1, 2])
獲取值:
let color = d[1] // Gets an optional-AnyObject?, wrapping "Green"
或者
let color = d[1] as! String
注意以下的錯誤代碼:
let d = NSDictionary(objects: [ 0, 1, 2], forKeys: [0, 1, 2])
let value = d[1] as! String //crash happened
為了防止這種情況發(fā)生,需要使用as?:
The as? operator returns an optional: if its first operand is not of the type given by its second operand, it returns nil instead of crashing
let d = NSDictionary(objects: [ 0, 1, 2], forKeys: [0, 1, 2])
if let value = d[1] as? String { // as? returns nil if d is not of type String?
print("OK") // As expected – use value as normal
} else {
print("Incorrect types") // Executed if d is not of type [Int: String]
}
或者
You can use the is keyword to check whether the dictionary is of the expected type before using it:
if d is [Int: String] { // Evaluate to true if d maps Ints to Strings
print("Is [Int: String]")
} else {
print("Incorrect types")
}
參考文獻
《Beginning iPhone Development with Swift 2 - Exploring the iOS SDK 》From page 777 to page 838.
聯(lián)系作者
- 評論
- xueyublue@gmail.com
- qq905375641