Penutupan pantas
Penutupan ialah blok lengkap kod fungsian yang boleh digunakan dalam kod atau digunakan untuk menghantar nilai sebagai parameter.
Penutupan dalam Swift adalah serupa dengan blok dalam C dan Objektif-C, serta fungsi tanpa nama dalam beberapa bahasa pengaturcaraan lain.
Fungsi global dan fungsi bersarang sebenarnya adalah penutupan khas.
Bentuk penutupan ialah:
全局函数 | 嵌套函数 | 闭包表达式 |
有名字但不能捕获任何值。 | 有名字,也能捕获封闭函数内的值。 | 无名闭包,使用轻量级语法,可以根据上下文环境捕获值。 |
Terdapat banyak pengoptimuman untuk penutupan dalam Swift:
Menyimpulkan parameter dan jenis nilai pulangan berdasarkan konteks
Dari satu baris ungkapan Pulangan tersirat dalam penutupan (iaitu, badan penutupan hanya mempunyai satu baris kod, pulangan boleh ditinggalkan)
Anda boleh menggunakan nama parameter yang dipermudahkan, seperti $0, $1 ( bermula dari 0, menunjukkan parameter ke-i...)
menyediakan sintaks penutupan mengekor (Sintaks penutupan mengekor)
Suatu susunan jenis yang diketahui
Penutupan Fungsi, fungsi penutupan ini perlu menghantar dua nilai dari jenis yang sama seperti elemen tatasusunan dan mengembalikan nilai Boolean untuk menunjukkan sama ada parameter pertama yang diluluskan diletakkan kedudukan sebelum atau selepas parameter kedua apabila pengisihan selesai. . Jika nilai parameter pertama muncul sebelum nilai parameter kedua, fungsi penutupan pengisihan perlu mengembalikan
true
, jika tidak, ia mengembalikanfalse
.
sintaks
Yang berikut mentakrifkan Parameter terima dan mengembalikan sintaks penutupan jenis yang ditentukan:
{(parameters) -> return type in statements }
Instance
import Cocoa let studname = { print("Swift 闭包实例。") } studname()
Hasil output pelaksanaan program di atas ialah:
Swift 闭包实例。
Borang penutupan berikut menerima dua parameter dan mengembalikan Nilai Boolean:
{(Int, Int) -> Bool in Statement1 Statement 2 --- Statement n }
Instance
import Cocoa let divide = {(val1: Int, val2: Int) -> Int in return val1 / val2 } let result = divide(200, 20) print (result)
Hasil output pelaksanaan program di atas ialah:
10
Ekspresi penutupan
Ungkapan penutupan ialah Satu cara untuk membina penutupan sebaris menggunakan sintaks ringkas. Ungkapan penutupan menyediakan beberapa pengoptimuman sintaks yang menjadikan penutupan penulisan mudah dan mudah.
Fungsi isihan
Pustaka standard Swift menyediakan fungsi yang dipanggil isihan, yang mengisih nilai dalam tatasusunan jenis yang diketahui mengikut fungsi penutupan yang anda sediakan untuk mengisih .
Selepas pengisihan selesai, kaedah sort(_:) akan mengembalikan tatasusunan baharu dengan saiz yang sama dengan tatasusunan asal, mengandungi unsur-unsur jenis yang sama dan unsur-unsur telah diisih dengan betul tidak boleh diubah suai dengan kaedah sort(_:) . Kaedah
sort(_:) perlu lulus dalam dua parameter:
Instance
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] // 使用普通函数(或内嵌函数)提供排序功能,闭包函数类型需为(String, String) -> Bool。 func backwards(s1: String, s2: String) -> Bool { return s1 > s2 } var reversed = names.sort(backwards) print(reversed)
Hasil output pelaksanaan program di atas ialah:
["S", "D", "BE", "AT", "AE"]
Jika rentetan pertama (s1) lebih besar daripada rentetan kedua ( s2 ), fungsi ke belakang mengembalikan benar, menunjukkan bahawa s1 sepatutnya muncul sebelum s2 dalam tatasusunan baharu. Untuk aksara dalam rentetan, "lebih besar daripada" bermaksud "berlaku kemudian mengikut abjad". Ini bermakna huruf "B" lebih besar daripada huruf "A" dan rentetan "S" lebih besar daripada rentetan "D". Ia akan diisih mengikut susunan abjad terbalik, "AT" akan diisih sebelum "AE".
Singkatan nama parameter
Swift secara automatik menyediakan fungsi singkatan nama parameter untuk fungsi sebaris Anda boleh memanggil terus parameter penutupan secara berurutan melalui $0, $1, $2.
Instance
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] var reversed = names.sort( {["S", "D", "BE", "AT", "AE"]> } ) print(reversed)
$0 dan $1 mewakili parameter jenis Rentetan pertama dan kedua dalam penutupan.
Output pelaksanaan atur cara di atas ialah:
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] var reversed = names.sort(>) print(reversed)
Jika anda menggunakan singkatan nama parameter dalam ungkapan penutupan, anda boleh meninggalkan takrifnya dalam senarai parameter penutupan dan memadankan nama parameter Yang disingkatkan jenis disimpulkan daripada jenis fungsi. Kata kunci dalam juga boleh diabaikan
Fungsi operator
Sebenarnya terdapat cara yang lebih pendek untuk menulis ungkapan penutupan dalam contoh di atas.
Jenis String
Swift mentakrifkan pelaksanaan rentetan tanda yang lebih besar daripada (>
), yang sebagai fungsi menerima dua parameter jenis String
dan mengembalikan nilai jenis Bool
.
Dan ini konsisten dengan jenis fungsi yang diperlukan oleh parameter kedua kaedah sort(_:)
.
Oleh itu, anda hanya boleh melepasi tanda lebih besar dan Swift secara automatik boleh membuat kesimpulan bahawa anda ingin menggunakan pelaksanaan fungsi rentetan tanda lebih besar:
["S", "D", "BE", "AT", "AE"]
Output pelaksanaan program di atas ialah:
func someFunctionThatTakesAClosure(closure: () -> Void) { // 函数体部分 } // 以下是不使用尾随闭包进行函数调用 someFunctionThatTakesAClosure({ // 闭包主体部分 }) // 以下是使用尾随闭包进行函数调用 someFunctionThatTakesAClosure() { // 闭包主体部分 }
Penutupan mengekor
Penutupan mengekor ialah ungkapan penutupan yang ditulis selepas kurungan fungsi dan fungsi menyokong memanggilnya sebagai parameter terakhir. { $0 > $1} selepas
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] //尾随闭包 var reversed = names.sort() {["S", "D", "BE", "AT", "AE"]> } print(reversed)
contoh
reversed = names.sort {func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor }> }
sort() ialah penutupan mengekori.
Hasil output pelaksanaan program di atas ialah:
import Cocoa func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor } let incrementByTen = makeIncrementor(forIncrement: 10) // 返回的值为10 print(incrementByTen()) // 返回的值为20 print(incrementByTen()) // 返回的值为30 print(incrementByTen())
Nota: Jika fungsi memerlukan hanya satu parameter, ungkapan penutupan, anda juga boleh meninggalkan
()
apabila menggunakan penutupan mengekor.10 20 30
Menangkap nilai
Penutupan boleh menangkap pemalar atau pembolehubah dalam konteks di mana ia ditakrifkan.
Walaupun domain asal di mana pemalar dan pembolehubah ini ditakrifkan tidak lagi wujud, penutupan masih boleh merujuk dan mengubah suai nilai ini dalam badan fungsi penutupan.
Bentuk penutupan paling mudah dalam Swift ialah fungsi bersarang, iaitu fungsi yang ditakrifkan dalam badan fungsi fungsi lain.
Fungsi bersarang boleh menangkap semua parameter fungsi luarannya serta pemalar dan pembolehubah yang ditentukan.
Lihat contoh ini:
import Cocoa func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor } let incrementByTen = makeIncrementor(forIncrement: 10) // 返回的值为10 incrementByTen() // 返回的值为20 incrementByTen() // 返回的值为30 incrementByTen() // 返回的值为40 incrementByTen() let alsoIncrementByTen = incrementByTen // 返回的值也为50 print(alsoIncrementByTen())
Fungsi makeIncrementor, ia mempunyai parameter jenis Int, dan ia mempunyai nama parameter luaran untukIncremet, yang bermaksud bahawa apabila anda memanggil, anda mesti menggunakan ini nama luaran. Nilai pulangan ialah fungsi ()-> Int
.
Dalam tajuk fungsi, pembolehubah runningTotal dan penambah fungsi diisytiharkan.
Fungsi incrementor tidak memperoleh sebarang parameter, tetapi runningTotal dan pembolehubah amaun diakses dalam badan fungsi. Ini kerana ia berbuat demikian dengan menangkap pembolehubah runningTotal dan jumlah yang sudah wujud dalam badan fungsi yang mengandunginya.
Memandangkan pembolehubah amaun tidak diubah suai, penambah sebenarnya menangkap dan menyimpan salinan pembolehubah itu dan salinannya disimpan bersama dengan penambah.
Jadi apabila kita memanggil fungsi ini, ia akan terkumpul:
50
Hasil keluaran pelaksanaan program di atas ialah:
rrreeePenutupannya ialah jenis rujukan
Dalam contoh di atas, incrementByTen ialah pemalar, tetapi penutupan yang ditunjukkan oleh pemalar ini masih boleh menambah nilai pembolehubah yang ditangkapnya.
Ini kerana fungsi dan penutupan adalah kedua-dua jenis rujukan.
Sama ada anda menetapkan fungsi/penutupan kepada pemalar atau pembolehubah, anda sebenarnya menetapkan nilai pemalar/pembolehubah kepada rujukan kepada fungsi/penutupan yang sepadan. Dalam contoh di atas, rujukan yang ditunjukkan oleh incrementByTen kepada penutupan adalah pemalar, bukan kandungan penutupan itu sendiri.
Ini juga bermakna jika anda menetapkan penutupan kepada dua pemalar/pembolehubah yang berbeza, kedua-dua nilai akan menunjukkan penutupan yang sama:
rrreeeKeluaran pelaksanaan program di atas ialah:
rreeee