方法
swift统一了函数和方法的语法格式,如果函数放在枚举,结构体,类以外定义,就是函数
如果放在枚举,结构体,类以内定义,就是方法
程序可以直接把方法赋值给函数类型的变量
class SomeClass { func test() { print("==test 方法==") } class func bar(msg:String) { print("==bar类型方法==, 传入参数为:(msg)") } } var sc = SomeClass() var f1 : ()->() = sc.test//这里不能加括号,添加括号就变成了方法调用,而不是将方法赋值给函数类型的变量 var f2 : (String)->Void = SomeClass.bar sc.test() f1() SomeClass.bar("test message") f2("test test test message")
结构体和枚举都是值类型,在默认情况下,值类型的实例方法不能改变该实例的存储属性,需要加mutating关键字
struct FkRect { var x : Int var y : Int var width : Int var height : Int mutating func moveByX(x:Int, y:Int){ self.x += x self.y += y } } var rect = FkRect(x: 20, y: 12, 200, height: 300) rect.moveByX(100, y: 80) print("(rect.x)") //可以使用可变方法直接改变枚举的实例 enum Planettt:Int { case Mercury = 0, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Nepturn mutating func next(){ if self.rawValue < 8 && self.rawValue > -1 { self = Planettt(rawValue: self.rawValue + 1)! } } mutating func prev(){ if self.rawValue < 8 && self.rawValue > -1 { self = Planettt(rawValue: self.rawValue - 1)! } } } var pt = Planettt.Venus pt.next() pt.next() pt.prev()
方法相当于一种以let声明的、类型为函数类型的存储属性
分析:如果程序使用函数类型定义存储属性,并将函数或闭包作为该属性的初始值,那么这个属性变成了什么呢?没错,这个属性就成了方法
func factorial(n:Int) ->Int { var result = 1 for idx in 1...n { result *= idx } return result } struct SomeStruct { var info:()->Void={ print("info") } static var fact:(Int) -> Int = factorial } var sccc = SomeStruct() sccc.info = { print("another bibo") } sccc.info() var n = 6 print(SomeStruct.fact(6)) SomeStruct.fact = { var result = 1 for idx in 1...$0{ result += idx } return result } print(SomeStruct.fact(6))
下标
下标和计算属性非常相似,但是下标比计算属性更灵活
下标的形参列表不支持指定外部参数,也不支持指定默认值
下标重载:一个类型可以包含多个下标,只要多个下标的形参列表不同(形参数量或者形参类型不同)
可以通过扩展来增加下标
struct FkRectt { var x : Int var y : Int var width : Int var height : Int subscript(idx : Int) -> Int{ get{ switch(idx) { case 0: return self.x case 1: return self.y case 2: return self.width case 3: return self.height default: print("no") return 0 } } set{ switch(idx) { case 0: self.x = newValue case 1: self.y = newValue case 2: self.width = newValue case 3: self.height = newValue default: print("no") } } } } var rectc = FkRectt(x: 20, y: 12, 3435, height: 3453) rectc[0] = 40 print(rectc[0])
可选链
class Companyy { var name = "feng" var addr = "guangzhou" init(name:String, addr:String){ self.name = name self.addr = addr } } class Employeeee { var name = "bai" var title = "keke" var company : Companyy! init(name:String, title:String){ self.name = name self.title = title } func info(){ print("name is (name)") } } class Customerr { var name = "" var emp : Employeeee? init(name:String){ self.name = name } } var cc = Customerr(name: "sunsun") var emp = Employeeee(name: "zhu", title: "kekefufu") cc.emp = emp emp.company = Companyy(name: "dandan", addr: "panpan") print("(cc.name) company is (cc.emp!.company.name)") /* 那么问题来了 如果这里的cc没有给emp赋值,那么输出语句会怎么样呢,会报错 这时候可以通过在访问链中强制解析的感叹号(!)换成问号(?),在隐式解析和后面也添加问号(?)后缀,如果其中一个步骤返回nil,那么整个访问链都返回nil,而不会崩溃 eg print("(cc.name) company is (cc.emp?.company?.name)") 这就是可选链的访问方式 */ /* 使用可选链调用方法 */ class Customeaa { var name = "" var emp : Employeeee? init(name:String){ self.name = name } let employees = [ Employeeee(name: "bai", title: "kefu"), Employeeee(name: "zhi", title: "xiaoshou"), Employeeee(name: "jin", title: "putonh"), Employeeee(name: "xing", title: "zhu") ] func findEmp(empName:String) -> Employeeee! { for emp in employees{ if emp.name == empName{ return emp } } return nil } } var c3 = Customeaa(name: "fuck") c3.findEmp("bai").info()//这里没有使用可选链,但是name是存在的,所以不会报错,有输出 c3.findEmp("ba")?.info()//这使用可选链来调用方法,虽然name是错误的,但是不会报错,也没有输出 /* 使用可选链调用下标 */ var dict = [Int : Customeaa]() dict[1] = Customeaa(name: "zhu") dict[2] = Customeaa(name: "sha") dict[1]?.findEmp("xing")?.info() dict[4]?.findEmp("xing")?.info()