Swift 関数

Swift 関数は、特定のタスクを実行するための独立したコードブロックです。

Swift は、C 言語スタイルの単純な関数から Objective-C 言語スタイルの複雑なメソッドまでを表現するために、統一された構文を使用します。

  • 関数宣言: コンパイラに関数の名前、戻り値の型、およびパラメータを伝えます。

  • 関数定義: 関数の本体を提供します。

Swift 関数には、パラメータ型と戻り値の型が含まれます:


関数定義

Swift で関数を定義するにはキーワード func を使用しますfunc。

関数を定義するとき、1 つ以上の入力パラメータと 1 つの戻り値の型を指定できます。

各関数には、その機能を表す関数名があります。関数名と対応する型のパラメータ値を使用して関数を呼び出します。関数にパラメータを渡す順序は、パラメータリストと同じでなければなりません。

関数の実引数を渡す順序は、仮引数リストと同じでなければならず、->その後、関数の戻り値の型を定義します。

構文

func funcname(形参) -> returntype
{
   Statement1
   Statement2
   ……
   Statement N
   return parameters
}

例

次に、関数名が サンプル で、仮パラメータのデータ型が String、戻り値も String である関数を定義します。

import Cocoa

func サンプル(site: String) -> String {
    return (site)
}
print(サンプル(site: "www.example.com"))

上記のプログラムを実行すると、出力結果は次のようになります:

www.example.com

関数呼び出し

関数名と対応する型のパラメータ値を使用して関数を呼び出すことができます。関数にパラメータを渡す順序は、パラメータリストと同じでなければなりません。

次に、関数名が サンプル で、仮パラメータ site のデータ型が String である関数を定義します。その後、関数を呼び出すときに渡す実引数も String 型でなければなりません。実引数は関数本体に渡されると、そのまま返され、返されるデータ型は String です。

import Cocoa

func サンプル(site: String) -> String {
    return (site)
}
print(サンプル(site: "www.example.com"))

上記のプログラムを実行すると、出力結果は次のようになります:

www.example.com

関数パラメータ

関数は 1 つ以上のパラメータを受け取ることができます。これらのパラメータは関数の括弧内にカンマで区切って記述されます。

次の例では、関数 サンプル にサイト名 name とサイトアドレス site を渡します。

import Cocoa

func サンプル(name: String, site: String) -> String {
    return name + site
}
print(サンプル(name: "サンプル:", site: "www.example.com"))
print(サンプル(name: "Google:", site: "www.google.com"))

上記のプログラムを実行すると、出力結果は次のようになります:

サンプル:www.example.com
Google:www.google.com

パラメータなし関数

パラメータなしの関数を作成できます。

構文:

func funcname() -> datatype {
   return datatype
}

例

import Cocoa

func sitename() -> String {
    return "サンプル"
}
print(sitename())

上記のプログラムを実行すると、出力結果は次のようになります:

初心者チュートリアル

タプルを関数の戻り値として使う

関数の戻り値の型には、文字列、整数、浮動小数点型などを指定できます。

タプルは配列に似ていますが、タプルの要素は任意の型にでき、丸括弧を使用します。

タプル(tuple)型を使用すると、複数の値を 1 つの複合値として関数から返すことができます。

次の例では、Int 配列内の最小値と最大値を見つける minMax(_:) という関数を定義しています。

import Cocoa

func minMax(array: [Int]) -> (min: Int, max: Int) {
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
}

let bounds = minMax(array: [8, -6, 2, 109, 3, 71])
print("最小值为 \(bounds.min) ,最大值为 \(bounds.max)")

minMax(_:) 関数は、2 つの Int 値を含むタプルを返します。これらの値は min と max としてラベル付けされているため、関数の戻り値を参照するときに名前でアクセスできます。

上記のプログラムを実行すると、出力結果は次のようになります:

最小值为 -6 ,最大值为 109

返されるタプルが nil でないことが確実でない場合は、オプショナルなタプル型を返すことができます。

タプル型の右括弧の後に疑問符を置くことで、オプショナルなタプルを定義できます。たとえば、(Int, Int)? や (String, Int, Bool)? などです。

注意
オプショナルなタプル型(例: (Int, Int)?)は、(Int, Int)?タプル内の要素がオプショナルな型(例: (Int?, Int?))と(Int?, Int?)は異なります。オプショナルなタプル型では、タプル全体がオプショナルであり、タプルの各要素の値だけがオプショナルなわけではありません。

前述のminMax(_:)minMax(_:) 関数は 2 つのIntInt 値を含むタプルを返します。ただし、関数は渡された配列に対してセキュリティチェックを一切行いません。もしarrayarray パラメータが空の配列の場合、上記で定義したminMax(_:)arrayarray[0]実行時エラーが発生します。

この「空の配列」の問題を安全に処理するために、minMax(_:)minMax(_:) 関数をオプショナルなタプル戻り値型を使用するように書き換え、配列が空の場合は nil を返します。nil:

import Cocoa

func minMax(array: [Int]) -> (min: Int, max: Int)? {
    if array.isEmpty { return nil }
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
}
if let bounds = minMax(array: [8, -6, 2, 109, 3, 71]) {
    print("最小值为 \(bounds.min),最大值为 \(bounds.max)")
}

上記のプログラムを実行すると、出力結果は次のようになります:

最小值为 -6,最大值为 109

戻り値なし関数

次は サンプル(_:) 関数の別のバージョンです。この関数は、サンプル 公式サイトの URL パラメータを受け取り、戻り値の型を指定せずに、String 値を返すのではなく直接出力します。

import Cocoa

func サンプル(site: String) {
    print("サンプル官网:\(site)")
}
サンプル(site: "http://www.example.com")

上記のプログラムを実行すると、出力結果は次のようになります:

サンプル官网:http://www.example.com

関数パラメータ名

関数のパラメータには、外部パラメータ名とローカルパラメータ名があります。

ローカルパラメータ名

ローカルパラメータ名は、関数の実装内部で使用されます。

func sample(number: Int) {
   println(number)
}

上記の例では、number はローカルパラメータ名であり、関数本体内でのみ使用できます。

import Cocoa

func sample(number: Int) {
    print(number)
}
sample(number: 1)
sample(number: 2)
sample(number: 3)

上記のプログラムを実行すると、出力結果は次のようになります:

1
2
3

外部パラメータ名

ローカルパラメータ名の前に外部パラメータ名を指定できます。空白で区切ります。外部パラメータ名は、関数呼び出し時に関数に渡すパラメータに使用されます。

次のように、2 つの関数パラメータ名を定義して呼び出すことができます。

import Cocoa

func pow(firstArg a: Int, secondArg b: Int) -> Int {
   var res = a
   for _ in 1..<b {
      res = res * a
   }
   print(res)
   return res
}
pow(firstArg:5, secondArg:3)

上記のプログラムを実行すると、出力結果は次のようになります:

125

注意
外部パラメータ名を指定した場合、関数を呼び出すときは必ず外部パラメータ名を使用しなければなりません。


可変引数

可変引数は、0 個以上の値を受け取ることができます。関数呼び出し時に、可変引数を使って関数のパラメータを指定でき、その数は固定されていません。

可変引数は、変数の型名の後に(...)を付けることで定義します。

import Cocoa

func vari<N>(members: N...){
    for i in members {
        print(i)
    }
}
vari(members: 4,3,5)
vari(members: 4.5, 3.1, 5.6)
vari(members: "Google", "Baidu", "サンプル")

上記のプログラムを実行すると、出力結果は次のようになります:

4
3
5
4.5
3.1
5.6
Google
Baidu
サンプル

定数、変数および I/O パラメータ

通常、関数内で定義されるパラメータはデフォルトで定数パラメータです。つまり、このパラメータは参照して使用することはできますが、その値を変更することはできません。

変数パラメータを宣言したい場合は、パラメータ定義の前に inout キーワードを付けると、このパラメータの値を変更できるようになります。

例:

func  getName(_ name: inout String).........

この場合、この name の値は関数内で変更できます。

通常、デフォルトのパラメータ受け渡しは参照渡しではなく値渡しです。したがって、関数内で渡されたパラメータを変更しても、元のパラメータには影響しません。渡されるのはこのパラメータのコピーにすぎません。

渡すパラメータを入力出力パラメータとして使用する場合は、パラメータ名の前に & 記号を付けて、その値が関数によって変更できることを示します。

例

import Cocoa

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}


var x = 1
var y = 5
swapTwoInts(&x, &y)
print("x 现在的值 \(x), y 现在的值 \(y)")

swapTwoInts(_:_:) 関数は、a と b の値を単純に交換します。この関数は、まず a の値を一時定数 temporaryA に格納し、次に b の値を a に代入し、最後に temporaryA を b に代入します。

注意すべき点は、someInt と anotherInt は swapTwoInts(_:_:) 関数に渡す前に、どちらにも & のプレフィックスが付けられていることです。

上記のプログラムを実行すると、出力結果は次のようになります:

x 现在的值 5, y 现在的值 1

関数型とその使用

各関数には特定の関数型があり、関数のパラメータ型と戻り値の型で構成されます。

func inputs(no1: Int, no2: Int) -> Int {
   return no1/no2
}

inputs 関数型は、2 つの Int 型のパラメータ(no1、no2)を持ち、Int 型の値を 1 つ返します。

例は次のとおりです:

import Cocoa

func inputs(no1: Int, no2: Int) -> Int {
    return no1/no2
}
print(inputs(no1: 20, no2: 10))
print(inputs(no1: 36, no2: 6))

上記のプログラムを実行すると、出力結果は次のようになります:

2
6

上記の関数は、2 つの Int パラメータ型を定義しており、戻り値も Int 型です。

次に、以下の関数を見てみましょう。この関数は、パラメータが String 型、戻り値が String 型として定義されています。

func inputstr(name: String) -> String {
   return name
}

関数は、パラメータがなく戻り値もない関数を定義することもできます。次に示すとおりです。

import Cocoa

func inputstr() {
   print("サンプル")
   print("www.example.com")
}
inputstr()

上記のプログラムを実行すると、出力結果は次のようになります:

サンプル
www.example.com

関数型を使用する

Swift では、関数型は他の型と同じように使用できます。たとえば、型が関数である定数または変数を定義し、適切な関数をそれに代入できます。

var addition: (Int, Int) -> Int = sum

解説:

addition という名前の変数を定義し、additionパラメータと戻り値の型はどちらも Int で、Intこの新しい変数をsummathFunc 関数にポイントさせます。

sumとadditionこれらは同じ型を持つため、上記の操作は合法です。

これで、addition を使って代入された関数を呼び出すことができます:

import Cocoa

func sum(a: Int, b: Int) -> Int {
   return a + b
}
var addition: (Int, Int) -> Int = sum
print("输出结果: \(addition(40, 89))")

上記のプログラムを実行すると、出力結果は次のようになります:

输出结果: 129

関数型をパラメータ型として、関数型を戻り値型として

関数をパラメータとして別のパラメータに渡すことができます:

import Cocoa

func sum(a: Int, b: Int) -> Int {
    return a + b
}
var addition: (Int, Int) -> Int = sum
print("输出结果: \(addition(40, 89))")

func another(addition: (Int, Int) -> Int, a: Int, b: Int) {
    print("输出结果: \(addition(a, b))")
}
another(addition: sum, a: 10, b: 20)

上記のプログラムを実行すると、出力結果は次のようになります:

输出结果: 129
输出结果: 30

関数のネスト

関数のネストとは、関数内で新しい関数を定義することで、外部の関数は関数内で定義された関数を呼び出すことができます。

例は以下のとおりです。

import Cocoa

func calcDecrement(forDecrement total: Int) -> () -> Int {
   var overallDecrement = 0
   func decrementer() -> Int {
      overallDecrement -= total
      return overallDecrement
   }
   return decrementer
}
let decrem = calcDecrement(forDecrement: 30)
print(decrem())

上記のプログラムを実行した出力結果は次のとおりです。

-30
その他の拡張