Swift言語:関数
概要
swiftの関数について仕様を確認しました。The Swift Programming Language (Swift 2.1) - Functions
引数なし
func hello() { print("hello World") } hello()
引き数あり
外部引き数名なし
第2引数は引き数名を付けないとコンパイルエラーになる
func calcTriangle(w: Float, h: Float) -> Float { return (w * h * 0.5) } calcTriangle(10.0, 20.0) --> コンパイルエラー calcTriangle(10.0, h: 20.0)
引き数名を明示的に省略することもできる。
入力を間違えやすくなるので使う場所を考える必要がある。
func calcTriangle2(w: Float, _ h: Float) -> Float { return (w * h * 0.5) } calcTriangle2(10.0, 20.0)
外部引き数名あり
外部引き数名を使った方がわかりやすい例
内部引き数名を省略形にすることはあるが、関数を呼び出す時には分かりやすい名前を指定する。
先頭の引数は省略可能だが、省略しない方がベター。
func calcTriangle3(base w: Float, height h: Float) -> Float { return (w * h * 0.5) } calcTriangle3(base: 10.0, height: 20.0)
引数を省略してもわかりやすい例
自然言語的に意味のある文になっている(say Hello To Tom)
関数名は、自然言語として読みやすい名前をつけるようにする(by Readable Code)
func sayHello(name: String) { print("Hello! " + name) } sayHello("Tom")
外部引数名が不要なケース
関数swap。1番目の引数と2番目の引数で値を入れ替えるので名前は意味を持たない。
func doSwap(inout a: Int, inout _ b: Int) { let tmp = a a = b b = tmp } var a = 10 var b = 100 swap(&a, &b) print("a = \(a), b = \(b)")
デフォルト引数値
引数の値を省略するとデフォルト値が適用される。
func someFunction(parameterWithDefault: Int = 12) { // function body goes here // if no arguments are passed to the function call, // value of parameterWithDefault is 12 } someFunction(6) // parameterWithDefault is 6 someFunction() // parameterWithDefault is 12
可変長引数
可変長引数にすると、引数の長さを不定にできる。
func arithmeticMean(numbers: Double...) -> Double { var total: Double = 0 for number in numbers { total += number } return total / Double(numbers.count) } arithmeticMean(1, 2, 3, 4, 5)
返値あり
単一返値
-> 型という書式で返値を宣言できる。
func min(array: [Int]) -> Int { var min = array[0] for n in array { if n < min { min = n } } return min } let minOfArray = min([1, -2, 3, 10, 5]) print("min = \(minOfArray)")
返値は、Optional型にすることもできる。
func minEx(array: [Int]) -> Int? { if array.isEmpty { return nil } var min = array[0] for n in array { if n < min { min = n } } return min } let minValue = minEx([1, -2, 3, 10, 5]) if let min = minValue { print("min = \(min)") }
複数返値
返値をタプルで宣言すると複数の値を返値にすることができる。
返値にも名前を付けることができる。
返値の値は、index(0,1,...)あるいは、名前(min, max)で取得できる。
func minMax(array: [Int]) -> (min: Int, max: Int) { var currentMin = array[0] var currentMax = array[0] for value in array[1..currentMax { currentMax = value } } return (currentMin, currentMax) } let bounds = minMax([8, -6, 2, 109, 3, 71]) print("min is \(bounds.min) and max is \(bounds.max)")
クロージャー
クロージャーの場合には、引数をタプルで渡すこともできる。
let f4: (String, Int) -> (Int, String) = { args in let (a, b) = args return (b, a) } let tuple = ("aaa", 1) f4(tuple)
ただし、引数に名前が付いている場合はダメみたい。
func test(a: String, b: Int) -> (Int, String) { return (b, a) } // Missing argument for parameter 'b' in call // test(tuple)
関数の引数・返値が関数の場合
関数の引数・返値に関数が使える。
引数の場合
func addTwoInts(x: Int, y: Int) -> Int { return (x + y) } func printMathResult(mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) { print("Result: \(mathFunction(a, b))") } printMathResult(addTwoInts, 3, 5) // prints "Result: 8"
返値の場合
func stepForward(input: Int) -> Int { return input + 1 } func stepBackward(input: Int) -> Int { return input - 1 } func chooseStepFunction(backwards: Bool) -> (Int) -> Int { return backwards ? stepBackward : stepForward } var currentValue = 3 let moveNearerToZero = chooseStepFunction(currentValue > 0) print("Counting to zero:") // Counting to zero: while currentValue != 0 { print("\(currentValue)... ") currentValue = moveNearerToZero(currentValue) } print("zero!") // 3... // 2... // 1... // zero!