特色swift
switch中比較元組數組
主要用戶循環體中終止循環閉包
break的使用有兩種方式框架
break // 沒有標籤 break label // 添加標籤 // break語句中標籤的使用 label1: for var x = 0; x < 5; x++ { // 標籤1 label2: for var y = 0; y > 0; y-- { // 標籤2 if x == y { break label1 // 默認是跳出標籤2,加上標籤,能夠直接跳出到指定循環 } print("(x,y) = (\(x),\(y))") } }
continue
的使用和break相似,可使用標籤指定繼續的循環ide
// continue語句中標籤的使用 label1: for var x = 0; x < 5; x++ { // 標籤1 label2: for var y = 0; y > 0; y-- { // 標籤2 if x == y { continue label1 // 默認是跳出標籤2,加上標籤,能夠直接跳出到指定循環 } print("(x,y) = (\(x),\(y))") } }
參數傳遞函數
func rectangle(W width:Int, H height:Int) -> Int { // 其中W\H是外部參數名,在外部調用這個方法時會顯示出來,提示這個參數是神馬意思 // width\height 是內部參數,在函數內部調用使用 return width * height }
func rectangle(#width:Int, #height:Int) -> Int{ // 其中W\H是外部參數名,在外部調用這個方法時會顯示出來,提示這個參數是神馬意思 // width\height 是內部參數,在函數內部調用使用 return width * height }
參數默認值設計
func rectangle(#width:Int = 100, #height:Int = 100) -> Int { // 其中W\H是外部參數名,在外部調用這個方法時會顯示出來,提示這個參數是神馬意思 // width\height 是內部參數,在函數內部調用使用 return width * height }
可變參數代理
func sum(numbers: Double... ) -> Double { var total: Double = 0 for num in numbers { total += num } return total }
參數的引用傳遞rest
func rectangle(inout width:Int, increased:Int = 1 ) { width += increased } var value:Int = 10 rectangle(&value) // 結果是11 rectangle(&value,100) // 結果是111
函數返回值code
func rectangleArea(width:Double, increased:Double = 1 ) -> (area:Double,height:Double) //返回面積和高度
函數類型
(Double, Double) -> Double //傳入寬高,計算面積
函數重載
函數返回值類型
、外部參數名
也能夠做爲不一樣函數的判斷標準嵌套函數
泛型就是在運行時才肯定類型的一種機制,這個C++中的泛型一模一樣
就是定義一個模板,使用多種場景
函數參數或者返回值到運行時才能肯定
func add(a:Int, b:Int) -> Int { return a + b } func add(a:Double, b:Double) -> Double { return a + b }
若是用泛型計算兩個數的和,能夠寫成下面這個樣
func add<T>)(a:T, b:T) -> T { return a + b } // 或者指定多重類型 func add<T,U>(a:T, b:U) -> T { return a + T(b) }
若是比較兩個類型的話,那麼必需要遵照Comparable
協議才能夠
func isEquals<T: Comparable>(a:T, b:T) -> Bool { return (a == b) }
閉包是自包含的匿名函數代碼塊,能夠做爲表達式、函數參數和函數返回值。
{ (參數列表) -> 返回值類型 in 語句組 }
完整版本
{(a:Int, b:Int) -> Int in return a + b }
簡化版本 {a,b in return a + b }
{a,b in a + b }
{$0 + $1}
swift會自動推到出參數類型,$0表示第一個參數,$1表示第二個參數let reslut:Int = {(a:Int, b:Int) -> Int in return a + b }(10, 89)
捕獲上下文中的變量和常量
捕獲值
。即使是定義這些常量或變量的做用域已經不存在,嵌套函數或閉包仍然能夠在函數體內或閉包內修改或引用這些值。swift中枚舉能夠存儲多種數據類型,並非真正的整數
// 默認並非整形 enum WeekDays { case Monday case Tuesday case Wednesday case Thursday case Friday } // 簡寫 enum WeekDays { case Monday, Tuesday, Wednesday, Thursday, Friday }
注意:在switch中使用枚舉類型時,語句中的case必須所有包含枚舉中全部成員,不能多也不能少,包括default語句。
指定沒枚舉的原始值,能夠是字符、字符串、整數、浮點數等
// 指定枚舉的原始值 enum WeekDays: Int { case Monday = 0 case Tuesday case Wednesday case Thursday case Friday }
原始值使用的話,要用到函數 toRaw()
和 fromRaw()
「?」 和 "!"
可選綁定 : 若是賦值不爲nil的話就執行if語句
if let result: Double? = divide(100,0) { print("success") } else { print("failure") }
強制拆封 : 使用 ! 來強制拆封
let result: Double? = divide(100,0) print(result!)
可選鏈
public
: 只要在import進所在模塊,那麼在該模塊中均可訪問internal
: 只能訪問本身模塊的任何internal實體,不能訪問其餘模塊中的internal實體,默認就是internal修飾符private
: 只能在當前源文件中訪問的實體。存儲屬性適用於類和結構體兩種類型,包括常量屬性(let
)和變量屬性(var
)
能夠對存儲屬性進行延遲加載
屬性觀察者
willSet
在設置新值以前調用didSet
在設置新值以後立刻調用var fullName: String { didSet { fullName = firstName + "." + secondName }
計算屬性自己不存儲數據,只從其餘存儲屬性中得到數據。類、結構體、枚舉均可以定義計算屬性
計算屬性只能使用var
修飾
var firstName: String = "Jone" var secondName: String = "Hu" // 計算屬性 var fullName: String { get { return firstName + "." + secondName } set (newValue) { let names = newValue.componentsSeparatedByString(".") firstName = names[0] secondName = names[1] } }
只讀計算屬性,只寫set方法便可,這是能夠省略set
,直接return
便可
var firstName: String = "Jone" var secondName: String = "Hu" // 計算屬性 var fullName: String { return firstName + "." + secondName }
一些集合類型,可使用下標訪問
/** * 定義二維數組,使用下標訪問數組 * 內部仍是一個一維數組,不過展現給外界的時一個二維訪問方式 */ struct DoubleArray { // 屬性定義 let rows: Int let cols: Int var grid: [Int] // 構造方法 init(rows: Int, cols: Int) { self.rows = rows self.cols = cols grid = Array(count: rows * cols, repeatedValue: 0) // 利用泛型建立一個數組 } // 下標定義 subscript(row: Int, col: Int) -> Int { get { return grid[row * col + col] } set (newValue) { grid[row * col + col] = newValue } } } // 使用二維數組 var arr2 = DoubleArray(rows: 10, cols: 10) // 初始化二維數組 for var i = 0; i < 10; i++ { for var j = 0; j < 10; j++ { arr2[i,j] = i * j } } // 輸出二維數組 for var i = 0; i < 10; i++ { for var j = 0; j < 10; j++ { print("\t \(arr2[i,j])") } print("\n") }
mutating
,稱之爲變異方法結構體和枚舉中靜態方法用static
,類中靜態方法使用class
一、結構體中的靜態方法
/** * 結構體中的靜態方法 */ struct Account { var owner: String = "Jack" static var interestRate: Double = 0.668 // 靜態方法 static func interestRateBy(amount: Double) -> Double { return interestRate * amount } func messageWith(amount: Double) -> String { let interest = Account.interestRateBy(amount) return "\(self.owner) 的利息是 \(interest)" } } // 調用靜態方法 print(Account.interestRateBy(10_000.00)) // var myAccount = Account() print(myAccount.messageWith(10_000))
二、枚舉中的靜態方法
/// 枚舉中的靜態方法 enum Account1 { case 中國銀行 case 中國工商銀行 case 中國建設銀行 case 中國農業因銀行 static var interestRate: Double = 0.669 // 靜態方法定義 static func interestBy(amount: Double) -> Double { return interestRate * amount } } // 靜態方法的調用 print(Account1.interestBy(10_000.00))
三、類中的靜態方法
/// 類中的靜態方法,使用關鍵字class class Account2 { var ower: String = "Jack" class func interestBy(amount: Double) -> Double { return 0.889 * amount } } // 調用靜態方法 print(Account2.interestBy(10_000.00))
init()
和析構函數deinit
convenience
關鍵字便可做爲便利構造器,便利構造器必須調用本類內部的其餘構造器override
final
is
as
Any
AnyObject
is
類型判斷as
類型轉換Any
任何類型,包括類和其餘數據類型AnyObject
任何類extension
protocol
weak reference
)unowned reference
)閉包中的循環引用的解決方法和上面的同樣,使用弱引用和無主引用
class Person { let firstName: String = "Jack" let secondName: String = "lu" /** * 解決閉包強循環引用 */ lazy var fullName: (String, String) -> String = { // [weak self] (firstName: String, secondName: String) -> String in [unowned self] (firstName: String, secondName: String) -> String in return firstName + secondName } }
OC和swift能夠混合開發
一、swift 調用 OC
二、OC調用swift
@objc
swift
類就不須要選擇新建swift文件,而是選擇Cocoa Touch Class
,而後選擇語言類型位swift