方法
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()