函數(shù)類型與閉包

函數(shù)類型

  • 函數(shù)類型定義:(參數(shù)類型1,參數(shù)類型2,……)->返回值類型
  • 函數(shù)類型是一種引用類型,類似于函數(shù)指針??梢詫⒑瘮?shù)類型應用于任何使用類型的地方:變量、參數(shù)、返回值。
  • 函數(shù)類型實例化支持:
    • 全局函數(shù)
    • 嵌套函數(shù)
    • 成員函數(shù)(實例方法 與 靜態(tài)方法)
func add(x:Double, y:Double)->Double{
  return x+y
}

func minus(x:Double, y:Double)->Double{
  return x-y
}

func mulitiply(x:Double, y:Double)->Double{
  return x*y
}

func divide(x:Double,y:Double)->Double{
  return x/y
}

class Matrix{
  var row=0.0
  var column=0.0

  init(row:Double ,colomn:Double){
    self.row=row
    self.column=column
}

  func process(x:Double, y:Double)->Double{
    return x*row+y*column
}
  
  static func invoke(x:Double, y:Double)->Double{
    return x*y+y*y
}
}
//函數(shù)類型作為變量
var compute:(Double, Double)->Double

compute=add //全局函數(shù)
let result1=compute(100,200)

compute=divide
let result2=compute(300,40)

var matrix=Matrix(row:10.0,column:20.0)
compute=matrix.process //實例方法
//compute.object=matrix
//compute.method=&process
compute(80,60)//JMP  compute.method

compute=Matrix.invoke //靜態(tài)方法
compute(30,40)

//函數(shù)類型作為參數(shù)
func process(math: (Double,Double)->Double,x:double,y:Double){
  let result=math(x,y)
  print("result:\(result)")  
}

process(multiply,x:30,y:50)

//函數(shù)類型作為返回值
func calculateFunction(symbol:String)->(Double,Double)->Double{
  switch(symbol){
  case "+":
           return add
  case "-":
           return minus
  case "*":
           return multiply
  case "/":
           return divide
  default:
      return add
  }
}

var calculate=calculateFunction("-")
let result3 = calculate(300,80)

//嵌套函數(shù)
func algorithmFunction(symbol:String)-> (Double, Double)->Double{
  func add(x:Double, y:Double)->Double{
    return x+y
  }

  func minus(x:Double, y:Double)->Double{
    return x-y
  }

  func mulitiply(x:Double, y:Double)->Double{
    return x*y
  }

  func divide(x:Double,y:Double)->Double{
    return x/y
  }
  switch(symbol){
    case "+":
           return add
    case "-":
           return minus
    case "*":
           return multiply
    case "/":
           return divide
    default:
      return add
  }
}

var algorithm=algorithmFuntion("/")
let result4 = algorithm(600,80)
函數(shù)類型的內(nèi)存模型.png

compute=全局函數(shù)時,對象指針為空
認識閉包Closure
=====================

  • 閉包是函數(shù)類型的實例,一段自包含的代碼塊,可被用于函數(shù)類型的變量,參數(shù)或返回值。

  • 三種閉包形式:

    • 全局函數(shù):具名函數(shù),但不捕獲任何值
    • 嵌套函數(shù):在函數(shù)內(nèi)部嵌套定義具名函數(shù),可捕獲包含函數(shù)中的值
    • 閉包表達式:匿名函數(shù)類型實例,不具名的代碼塊,可捕獲上下文中的值
  • 閉包是引用類型,閉包變量拷貝具有引用語義。

  • 閉包和函數(shù)類型實例擁有同樣的內(nèi)存模型。

class Rectangle {
  var width=0
  var length=0

  init(width:Int, length:Int){
    self.width=width
    self.length=length
  }
}

func <= (left: Rectangle, right: Rectangle) -> Bool {
  return left.width*left.length<=right.width*right.length
}

func compare(first:Rectangle, second: Rectangle)->Bool{
  return first.width*first.length<=second.width*second.length
}

var rects = [Rectangle(width:6,length:7),
             Rectangle(width:5,length:8),
             Rectangle(width:9,length:6)]

//函數(shù)類型對象
/*
func sort(@noescape isOrderedBefore: (Self.Generator.Element,Self.Generator.Element) -> Bool) -> [Self.Generator.Element]
*/
//func sort(isOrderedBefore:(Rectangle,Rectangle)->Bool)->[Rectangle]

var predict:  (Rectangle,Rectangle)->Bool
predict=compare
rects.sort(predict)

rects.sort(compare) //不用上面那樣繞


//閉包表達式
rects.sort({(first:Rectangle, second:Rectangle)->Bool in

  return first.width*first.length<=second.width*second.length
})


let expression={(first:Rectangle, second:Rectangle)->Bool in
  return first.width*first.length<=second.width*second.length
}
rects.sort(exprssion)//也可以這么寫

//自動類型推斷
rects.sort({first,second in
  return first.width*first.length<=second.width*second.length
})

//單表達式省略return
rects.sort({first,second in first.width*first.length<=second.width*second.length})

//參數(shù)縮略形式
rects.sort({$0.width*$0.length<=$1.width*$1.length})

//操作符縮略式
rects.sort( <= ) //rects.sort(compare)

//尾隨閉包
rects.sort{
  first,second in
  first.width*first.length<=second.width*second.length
}

rects.sort{$0.width*$0.length<=$1.width*$1.length}

//自動閉包
var cities = ["Beijing","shanghai","New York","Paris","London"]
print(cities.count)

let filter = {cities.removeLast()}//()->String
print(cities.count)

print("Deleting\(filter())!")
print(cities.count)

閉包表達式

{(參數(shù)1,參數(shù)2……)->返回值類型 in
語句塊
}

  • 幾種簡化縮寫形式:
    • 自動類型推斷:省略參數(shù)類型和返回值類型
    • 單表達式閉包可以省去return關(guān)鍵詞。
    • 使用參數(shù)縮略形式$0,$1...省略參數(shù)聲明和in
    • 將操作符函數(shù)自動推導為函數(shù)類型
    • 尾隨閉包:當閉包表達式為函數(shù)最后一個參數(shù),可將其寫在括號后
    • 自動閉包:不接受任何參數(shù),直接返回表達式的值。允許延遲計算

函數(shù)類型與閉包的變量捕獲

  • 函數(shù)類型和閉包可以捕獲其所在上下文的任何值:

    • 函數(shù)參數(shù)
    • 局部變量
    • 對象實例屬性
    • 全局變量
    • 類的類型屬性
  • 如果捕獲值生存周期小于閉包對象(參數(shù)和局部變量),系統(tǒng)會將被捕獲的值封裝在一個臨時對象里,然后在閉包對象上創(chuàng)建一個對象指針,指向該臨時對象。

  • 臨時對象和閉包對象之間是強引用關(guān)系,生存周期跟隨閉包對象。

var data=100

//捕獲實例屬性
class Rectangle{
  var width=0
  var length=0

  static var max=100

  init(width:Int,length:Int){
    self.width=width
    self.length=length
  }

  func getComputeHandler()->() -> Int{
    return {
      return self.width*self.length
    }
  }
}
var rect=Rectangle(width:10,length:20)
var handler=rect.getComputeHandler()
handler()

//捕獲參數(shù)或局部變量
func addHandler(var step: Int) -> () -> Int {
  var sum = 0
  return {
    sum += step
    data++
    Rectangle.max++
    step++
    return sum
  }
/*  func add() ->Int {
    sum+=step

    return sum  
  }
  return add*/
  
}
let addByTen=addHandler(10)

addByTen()
addByTen()
addByTen()
print(data)
print(Rectangle.max)

let addBYSix=addHandler(6)

addBySix()
addBySix()
addBySix()
print(data)
print(Rectangle.max)

/*class AddHelper {
  var sum=0
  var step=0

  func add() -> Int {
    self.sum+=self.step
    return self.sum
  }
}

func addHandlerHelper(step: Int) -> () -> Int {
  let sum=0
  let obj=AddHelper()
  obj.sum=sum
  obj.step=step
  let closuer=obj.add
  return closuer
}

let addByTen=addHandlerHelper(10)

print(addByTen())
print(addByTen())
print(addByTen())

let addByTen=addHandlerHelper(6)

print(addBySix())
print(addBySix())
print(addBySix())*/
捕獲值的內(nèi)存模型.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容