kitoko552.memo

kitoko552のメモ

Swiftにおける関数定義の基本

※この記事はQiitaにも投稿されています。

Swiftにおける関数定義の基本 - Qiita

inout

Swiftにはポインタという概念がありませんが、inoutを使うことで、関数の引数をポインタとして受け取り値を直接いじるCのような書き方ができます。 inoutを使用した関数の呼び出し方は、普通の関数と違って以下のように実引数の変数の前に&をつけて呼ぶことになります。

func square(inout x:Int, inout y:Int) {
    x = x * x
    y = y * y
}

/* 以下呼び出し側 */
var x = 2
var y = 4
square(&x, &y) // x=4, y=16になる

しかし、Swiftはタプルを使うことによって、返り値を複数指定できるため、inoutを使わなくても複数の値を返す関数を定義することができます(引数に構造体を指定することでも、複数の値を返すことができます)。

func square(x:Int, y:Int) -> (Int, Int) {
    return (x * x, y * y)
}

/* 以下呼び出し側 */
var x = 2
var y = 4
var res = square(x, y) // res.0=4, res.1=16になる

外部引数名

Swiftでは、関数を呼び出す際に引数の意味が伝わるよう、引数にキーワード(外部引数名)をつけることができます。

// 以下のように外部引数名(widthとheight)をつけることができる。
// wとhを内部引数名と呼ぶ。
func area(width w:Int, height h:Int) -> Int {
    return w * h
}

/* 以下呼び出し側 */
// 呼び出し側の実引数が何を表しているのかが明確になる。
let res = area(width: 5, height: 6)

また、以下のように仮引数の前に#を書くことで、内部引数名と外部引数名を同じにすることもできます。

func area(#width:Int, #height:Int) -> Int {
    return width * height
}

/* 以下呼び出し側 */
let res = area(width: 5, height: 6)

引数に用いるvar

Swiftでは、基本的に関数の引数の値を関数内で変更することができません。 しかし、仮引数の前にvarを書くことで変更可能になります。

func area(var width:Int, var height:Int) -> Int {
    // 引数の値を変更できる。
    width += 1
    height += 1
    
    return width * height
}

/* 以下呼び出し側 */
var w = 5
var h = 6
let res = area(w, h) // res=42
// w, hはそれぞれ5, 6のまま

同様にletを書くこともできますが、これは何も書かないときと同じなので、変更しないことを明示的に示したいときに使います。

オーバーロード

Swiftでは、以下のいずれかが異なれば、同名の関数を定義することができます。

  • 引数の個数
  • 引数の型
  • 返り値の型
  • 外部引数名

したがって、以下のすべてを定義してもコンパイルエラーになりません。

func area(w:Int, h:Int) -> Int {
    ...
}

// 引数の個数が異なる
func area(a:Int, b:Int, h:Int) -> Int {
    ...
}

// 引数の型が異なる
func area(w:Double, h:Double) -> Int {
    ...
}

// 返り値の型が異なる
func area(w:Int, h:Int) -> Double {
    ...
}

// 外部引数名が異なる
func area(width w:Int, height h:Int) -> Int {
    ...
}

// 外部引数名が異なる
func area(hoge w:Int, foo h:Int) -> Int {
    ...
}

ただし、呼び出し側で引数や返り値の型を意識する必要があります。

var w = 5
var h = 6
// let res = area(w, h) コンパイルエラー
// area関数にはIntを返すものとDoubleを返すものとがあるため、
// resの型がわからないとどの関数を呼べばいいかわからない

// 型をちゃんと指定する
let res : Int = area(w, h)

※この記事は以下の本を参考にしています。

詳解 Swift

詳解 Swift