Swift語法學習筆記1:變量與數(shù)據(jù)類型

我把自己學習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?

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)系作者

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Swift 介紹 簡介 Swift 語言由蘋果公司在 2014 年推出,用來撰寫 OS X 和 iOS 應用程序 ...
    大L君閱讀 3,445評論 3 25
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 4,202評論 1 10
  • 基礎部分(The Basics) 當推斷浮點數(shù)的類型時,Swift 總是會選擇Double而不是Float。 結合...
    gamper閱讀 1,509評論 0 7
  • 一直沒有時間好好看一下swift,最近復習了一遍語法,這里記錄swift學習過程中遇到的一些問題和要點,和Obje...
    bomo閱讀 2,563評論 0 25
  • 上圖是我最佳拍檔、今天與他分享了中國式眾籌:楊眾籌首倡的中國式眾籌是在眾創(chuàng)實踐中產(chǎn)生的重大理論創(chuàng)新,是經(jīng)系列案例驗...
    南輝閱讀 179評論 0 0

友情鏈接更多精彩內容