特色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