swiftクロージャーのサンプルコード
佐藤剛士氏によるGitHub Gist記事「ClosureSample.swift」をSwift5版、且つ非Playgroundで書き直してみました。
…結局、何某かのClassなりの中で利用する訳だし。
import Foundation
//
// Closure_Sample.swift
// SwiftTryCatch
//
// Created by ISHIKAWA Koutarou on 2020/07/26.
//
class Closure_Sample: NSObject {
override init() {
<#code#>
}
//MARK: - ネスト関数でクロージャーを作る。
func outer() -> () -> Void {
var x: Int = 10
func inner() {
print("X is \(x)")
//inner関数で定義されていないx変数を操作している。
x = x + 1
}
//関数を返り値として返している
return inner
}
func aaa() {
let f: () -> Void = self.outer()
// -> X is 10
f()
// -> X is 11
f()
// -> X is 12
f()
}
//MARK: - sort(_:)メソッドを使ってクロージャーをもっと見てみる
var name: Array<String> = [ "Chris", "Alex", "Ewa", "Barry", "Daniella" ]
/// <#Description#>
/// - Parameters:
/// - s1: <#s1 description#>
/// - s2: <#s2 description#>
/// - Returns: <#description#>
func backwards(s1: String, _ s2: String) -> Bool{
return s1 > s2
}
/// <#Description#>
func bbb1() {
let reversed: () = self.name.sort(by: self.backwards)
print(reversed)
}
/// 無名関数で実行してみる
func bbb2() {
let reversed: () = self.name.sort(by: { (s1: String, s2: String) -> Bool in
return s1 > s2
})
print(reversed)
}
/// Swiftは型を推定。配列の型は推定できるから「(String, String) -> Bool」の記述は省略できる
func bbb3() {
let reversed: () = self.name.sort(by: {
s1, s2 in return s1 > s2
})
print(reversed)
}
/// 処理を単式で書いた場合は戻り値は暗黙に返される。なので'return'の文字はいらない
func bbb4() {
let reversed: () = self.name.sort(by: { s1, s2 in s1 > s2 })
print(reversed)
}
/// 略式の引数名。クロージャーには自動的に引数に名前($0,$1,$2)がつけられている。これを使うと、引数の定義をしなくてもいいし、 inの文字もいらない
func bbb5() {
let reversed: () = self.name.sort(by: { $0 > $1 })
print(reversed)
}
/// オペレーター関数を使う。SwiftのString型は「>」が使える。「>」は2つのString型引数をもち、戻り値としてBool型を返す。「sort(_:)」にぴったり
func bbb6() {
let reversed: () = self.name.sort(by: >)
print(reversed)
}
/// sort関数でもTrailing Closuresを使ってみる
func bbb7() {
let reversed: () = self.name.sort() {
$0 > $1
}
print(reversed)
}
/// Trailing Closuresで、引数がクロージャー以外なかったら「()」を省略できる
func bbb8() {
let reversed: () = self.name.sort{
$0 > $1
}
print(reversed)
}
//MARK: - Trailing Closures。関数の引数の末尾(最後)がclosureを受け取る場合、処理部分を外に配置できる。
/// closureを受け取る関数の定義。「(Int, Int) -> Int」という型の関数を受け取る
/// - Parameters:
/// - a: <#a description#>
/// - b: <#b description#>
/// - closure: <#closure description#>
/// - Returns: <#description#>
func add(_ a: Int, b: Int, closure: (Int, Int) -> Int) -> Int {
return closure(a, b)
}
/// 「add()」を普通に使う
func iii() {
var _: Int = self.add(1, b: 5, closure: { (a: Int, b: Int) -> Int in
return a + b
})
}
/// Trailing版。実際の処理を引数の「()」の外に置いている。
func jjj() {
var _: Int = self.add(1, b: 5) {
$0 + $1
}
}
}