swift 中所有的數(shù)據(jù)類型都是由三種不同的數(shù)據(jù)結構(枚舉、結構體、類)中的某一種實現(xiàn)的。
枚舉和結構體在代碼中以值得方式進行傳遞,類是通過引用的方式進行傳遞的。
基本數(shù)據(jù)類型都是基于結構體實現(xiàn)的,它們可能會通過屬性或方法實現(xiàn)一些額外的功能
swift 是一門強類型語言,意味著每一個變量類型在編譯時期就已經(jīng)確定,并且在其生命周期中只能春初固定類型的值
變量的聲明
var itemCount: Int = 0只要在讀取變量之前設置初始值即可swift中有一個功能叫做類型推斷,如果編譯器能夠從初始值中獲取到足夠多的信息來推斷類型,那么在聲明時可省略類型,如
var itemCount = 0-
字符串插值可將變量、常量和其他表達式的值添加到字符串中,在括號中包含一個變量或表達式,再用一個反斜杠\進行轉(zhuǎn)義,最后直接添加到字符串中。如:
var itemCount = 34 print("there are \(itemCount) items") if 和 for 可省略檢測表達式中的括號
-
區(qū)間表達式
for i in 0 ..< 10 {} for i in 0 ... 10 {}
-
如果要將某種類型轉(zhuǎn)化為另一種類型,可以創(chuàng)建一個新的所期望的實例,然后用初始值設置這個新實例的初始值
var a: Int32 = 10 var b: Int64 = Int64(a) 小數(shù)可以使用Float 和 Double 類型,F(xiàn)loat是32位的,Double 是64位的,這與設備的架構無關。如果未指定類型,編譯器總推斷為Double類型。
布爾型,swift只有表達式顯示返回一個布爾型才能被用于布爾值的聲明。
字符串,只需簡單的置于雙引號內(nèi)。String是Character類型值得集合,每個Character就是一個Unicode字符。 String使用count()函數(shù)來判斷一個字符串中有多少個字符??梢允褂谩?”運算符將字符串拼接起來,也可以使用“+=”運算符將一個字符串拼接到另一個字符串中。可以直接使用“==”來判斷兩個字符串是否相等。
數(shù)組 swift中數(shù)組是集合類型中的一種,用來存儲相同類型的有序列表。聲明數(shù)組時,必須指定數(shù)組包含的類型,一旦確定類型,就只能存儲這一類型的數(shù)據(jù)。swift中可以把結構體、枚舉、類添加到數(shù)組中,由于所有基本數(shù)據(jù)類型都是用結構體實現(xiàn)的,所以他們都可以放到數(shù)組中。
-
可空類型使程序員不得不考慮什么時候值可能為空,并且強制規(guī)定不予許用普通的類型存儲空值。
if let someValue = someOptional { // 合并了非空判斷和拆箱 // 正常使用someValue } -
閉包表達式
{(parameters) -> returnType in statements } -
如果元組中的某個值你不需要,再分解時你可以用“_”替代,再分解時編譯器會忽略該值。
let a = (1, "dfg", "swe") let (_, charater, _) = a ---> charater: String = "dfg"
swift 中的 switch 語句沒有了break 可以用fallthrough 穿越,case不僅可以匹配值,也可以匹配范圍、模式并進行值綁定。
-
枚舉
enum NetworkConnection { case NotConnection case WiFi case Cellular } var b = NetworkConnection.WiFi b = .Cellular // 推斷出b的類型之后,就可用省略類型的點標記法來更新變量值 在使用這個類的實例前,你必須初始化所有屬性。其中有默認值的屬性會被自動初始化,沒有默認值的必須在
init()方法中設置初始值init()方法有特殊的權限,能在實例中設置或改變常量屬性,甚至能在同一個init()方法中進行多次設置或改變。在init()方法返回或完成之前,常量屬性都還沒有被鎖定。能夠完全初始化對象的
init()方法叫做指定初始化函數(shù),依賴其他方法初始化對象的init()方法叫做便捷初始化函數(shù)。我們通過使用convenient關鍵字來聲明一個便捷初始化函數(shù)。當繼承起作用時,初始化變得稍微有些復雜。當一個類繼承父類,他可能繼承也可能不繼承
init()方法。①如果子類提供自己的指定初始化函數(shù),他將不繼承任何父類的init()方法。②如果子類只提供便捷初始化函數(shù)或者不提供init()方法,它將繼承父類中所有init()方法。這是swift的部分安全特性。存儲型屬性通過附加在類實例中的變量來體現(xiàn),可以簡單的以
varlet聲明,并且賦予默認值或在對象實例化時初始化。-
計算型屬性沒有相關聯(lián)的變量,因此并不直接存儲任何數(shù)據(jù)。他們被間接訪問或計算類中的其他數(shù)據(jù)??梢酝ㄟ^聲明一個setter 和 getter 方法來使用計算型屬性:
// 計算型屬性(只讀屬性) var largePictureURLs: [NSURL]? { return retweeted_status == nil ? storeLargePictureURLs : retweeted_status?.storeLargePictureURLs } // 計算型屬性 (非只讀屬性) var d: Int { get { return a + b } set { a = newValue } } -
屬性觀察者
var source: String? { didSet { // 重新計算來源并且保存 // 在 didSet 中,給 source 再次設置值,不會調(diào)用 didSet source = "來自于 " + (source?.cz_href()?.text ?? "") } }
-
延遲屬性,當一個對象實例化時,其所有屬性都必須被初始化,這樣做開銷可能非常大或根本不需要。swift引入了
lazy關鍵字,如果在一個屬性開頭加上lazy關鍵字,編譯器就不強制初始化該屬性,并將其初始化推遲至屬性的第一次使用時。lazy var logo: UIImage = { let data = try! Data(contentsOf: URL(fileURLWithPath: "cache/xixi.png")) let image = UIImage.init(data: data, scale: 0.8) return image! }() -
協(xié)議
/// 微博 Cell 的協(xié)議 /// 如果需要設置可選協(xié)議方法 /// - 需要遵守 NSObjectProtocol 協(xié)議 /// - 協(xié)議需要是 @objc 的 /// - 方法需要 @objc optional @objc protocol WBStatusCellDelegate: NSObjectProtocol { /// 微博 Cell 選中 URL 字符串 @objc optional func statusCellDidSelectedURLString(cell: WBStatusCell, urlString: String) } 訪問控制,public 是最高一級,標記為public的實體可被同模塊中的任何文件使用,或被引用了該模塊的其他模塊中的任何文件使用。internal 是默認級別,internal實體可被同模塊中的任何文件使用。private是最低一級,private實體僅在其被定義的代碼段中可用。
swift 中可空類型,swift的類型系統(tǒng)消除了為空的混亂情況,強制使用
nil來代表無效值,同時明確規(guī)定,只有可空類型允許存儲nil值。-
可控綁定
if let w = f { print(w) } -
強制拆箱
var a: Int? = 3 let b = a! -
可空鏈
let innerString = outer.inner?.innerInner?.innerMostStr?可空鏈的語法類似于強制拆箱,只不過用?代替了!,語法被簡化的同時保證了可控類型的安全使用。在可空鏈的每一個節(jié)點上,節(jié)點的可空值都會被檢測,只有在值存在的情況下,下一步操作才會繼續(xù)執(zhí)行。如果任何一個節(jié)點返回nil,則整個可空鏈返回nil,當然可空鏈也會帶來一個負面效應,如果最后一步操作返回的是非可空值,他也會被隱式的包裝為可空類型。
-
帶隱式拆箱的可空
數(shù)據(jù)在某些情況下具備這樣一個特點,它們一旦初始化(一般此類數(shù)據(jù)會被延遲初始化)之后就不會為空。而因為初始化之前它們有可能為空,我們不便用非可空類型存儲它們。如果用可空類型定義的話,又不想在初始化之后每次都進行非空檢查,對于這樣的情況swift 提供了“帶隱式拆箱的可空類型”。
可空類型和帶隱式拆箱的可控類型不同之處在于二者的定義方法和訪問方法。但是在可控綁定方面,二者是一致的。如下創(chuàng)建(用!取代?):
var implicitlyUnwrapped: String!盡管帶隱式拆箱的可空在許多方面和標準和標準的可空是一樣的,但前者和后者是不同的enum 類型,這兩個enum類型不能對接。 因為帶隱式拆箱的可空總是被假定是有值的,因此在訪問他們時,不需要進行強制拆箱。
帶隱式拆箱的可空類型要求開發(fā)者自己確保值總是有效的,如果你不為它指定一個值,那么在使用帶隱式拆箱的可空時將會引起錯誤。 其在處理依賴對象的初始化時用的最多。 你應該在一旦初始化即可保證有值的對象上使用帶隱式拆箱的可空類型,如果這個對象有可能被改變?yōu)閚il,你應當使用標準的可空類型。
?
-
泛型
編寫代碼時,對象實例的類型是不可知的,在使用時才指定實際的類型。使用泛型編程,通過將功能從具體的類型中抽象出來,可以為函數(shù)或數(shù)據(jù)類型創(chuàng)建通用的模板。它在swift中是一個關鍵的概念。使用泛型使得你通過定義需要的數(shù)據(jù)種類以及編譯器自動創(chuàng)建特定類型的代碼,從而專注于如何與數(shù)據(jù)交互。 泛型函數(shù)提供了原型功能定義,(編譯器可以)按需構造眾多的重載函數(shù),這種構造是自動的。 泛型函數(shù)的聲明與普通函數(shù)的聲明類似,只需要額外加入一列類型參數(shù)。
func isASubclassOfNSObject<T>(objectToTest:T) -> Bool { return objectToTest is NSObject }
-
函數(shù)
func sayHello(number: Int, word: String) { print("hello") }這個例子中函數(shù)的參數(shù)只有本地參數(shù)名,本地參數(shù)名用于在函數(shù)體中使用傳入的參數(shù)值,同時這個本地參數(shù)名對于調(diào)用者是無效的。但是為了讓函數(shù)的調(diào)用者明白參數(shù)的具體含義,并讓調(diào)用者根據(jù)名稱而不是順序來傳參,會添加額外的參數(shù)名叫做外部參數(shù)名。外部參數(shù)名放在本地參數(shù)名之前
func sayHello(number: Int, withWord word: String) { print("hello") }如果你想忽略成員函數(shù)的外部參數(shù)名,則用“_”作為參數(shù)的外部參數(shù)名即可。
-
參數(shù)的默認值
swift允許為參數(shù)指定默認值。如果調(diào)用時缺省某個參數(shù),那么函數(shù)會使用該參數(shù)的默認值進行調(diào)用。要定義參數(shù)默認值,在參數(shù)類型聲明后使用“=”即可
func hah(i: Int = 4, numbers: Int...) -> Int { var max = i for number in numbers { if number > max { max = number } } return max }調(diào)用:
let b = hah(numbers: 12,34,5) -
可變參數(shù)
允許函數(shù)接收0或多個值作為參數(shù),其需要在參數(shù)類型后加上“…”,在函數(shù)體內(nèi)部可變參數(shù)被視為同一類型的數(shù)組,如上邊的例子,一個函數(shù)只能定義一個可變參數(shù),同時可變參數(shù)只能是函數(shù)的最后一個參數(shù)。
-
inout參數(shù)
允許函數(shù)直接改變外部傳入的參數(shù)值。func hah(a: Int, b: inout Int) -> Int { b += a return b }var f = 7 let c = hah(a: 3, b: &f) print(c, f) -
返回類型
如果定義函數(shù)時沒有返回值,這個函數(shù)仍然會有一個返回類型:()。如果一個函數(shù)既沒有參數(shù)有沒有返回值,這個函數(shù)的類型為:( ) -> ( )。元祖作為函數(shù)返回值:
func processNumbers(array: [Int]) -> (sum: Int, max: Int) { var sum = 0 var max = Int.min for i in array { sum += i if i > max { max = i } } return (sum, max) } -
閉包
閉包的好處在于不用命名和聲明函數(shù)就能在代碼段中使用參數(shù)并返回值,同時可以像函數(shù)一樣,用函數(shù)作為參數(shù)或返回值。
閉包作為函數(shù)參數(shù)
let numbers = [2, 6, 7, 2, 9] let abc = numbers.sorted { (a: Int, b: Int) -> Bool in return a > b }參數(shù)及返回值的類型推斷
由于在函數(shù)聲明時,參數(shù)和返回值類型都是事先聲明的,因此閉包的類型信息可以從中推斷,我們可以忽略閉包中的類型信息:
let numbers = [2, 6, 7, 2, 9] let abc = numbers.sorted { a, b in return a > b }通常閉包都會有一個返回值,因此當閉包僅由一條return 語句構成時,return 關鍵字可以省略
let numbers = [2, 6, 7, 2, 9] let abc = numbers.sorted { a, b in a > b}閉包參數(shù)自動含有另外一種形式的參數(shù)名,例如$0、$1、$2······,根據(jù)參數(shù)的順序依次遞增,你可以不提供參數(shù)名列表,而直接使用這種按序號命名的參數(shù)名
let numbers = [2, 6, 7, 2, 9] let abc = numbers.sorted { $0 > &1 }總結
let numbers = [2, 6, 7, 2, 9] let abc = numbers.sorted { (a: Int, b: Int) -> Bool in // 常規(guī) return a > b } let abb = numbers.sorted { a, b in // 省略類型 return a > b } let aaa = numbers.sorted { a, b in a > b } // 省略return let bbb = numbers.sorted { $0 > $1} // 閉包按序號命名的參數(shù)名 -
尾隨閉包
有些函數(shù)最后一個參數(shù)往往使用了函數(shù)類型,swift為它提供了一種簡化的寫法:尾隨閉包。它將參數(shù)中的最后一個閉包寫在參數(shù)列表之后, 如果函數(shù)參數(shù)中只有一個閉包參數(shù)的話,圓括號是可選的,可以像上面一樣忽略