#author("2016-05-25T05:50:44+00:00","default:nitta","nitta") #author("2016-05-30T13:21:10+00:00","default:nitta","nitta") [[Swift]] *Swift/関数 [#k953c051] ** 基本的な関数定義と呼び出し [#vfefb2a6] 関数定義 func 関数名(変数名: 型, [外部引数名 変数名: 型]...) -> 返り値の型 { 文 } 関数呼び出し 関数名(値, [外部引数名 値]...); 外部引数名は省略すると変数名と同じになる。 関数呼び出しで外部変数名を指定したくない場合は、関数定義のときに定義外部変数名として _ を使う。 外部変数名は一つの関数定義で同じものが複数回使われていても構わない。 関数呼び出し側の変数の値を関数の中で変更する場合は、C言語ではポインタを引数として渡すが、 Swiftではinout引数を使う。inout変数は外部引数名や_が指定されている場合はそれよりも前に置く。 func mySwap(inout a: Int, inout _ b:Int) { let t = a; a = b; b = t } var x = 1 var y = 2 swap(&x,&y) // 実行後は x = 2, y = 1 となる **関数の引数のデフォルト値 [#r962a2af] 関数の引数にデフォルト値を指定する場合は "= 式"で記述する。 デフォルト値は定数である必要はなく、グローバル変数などでも可。 同時にinoutを宣言することはできない。 let fontSize: Float = 12.0 func setFont(name:String, size:Float = fontSize, bold:Bool = false) { print("\(name) \(size)" + (bold ? " [B]" : "")) } func setGray(level:Int = 255, _ alpha:Float = 1.0) { print("Gray=\(level), Alpha=\(alpha)") } setFont関数は第1引数以外を省略できる。デフォルト値が指定されている変数は順番が変更されてもOK(らしい?) setFont("Courier"); // Courier 12.0 setFont("Courier", bold:true); // Courier 12.0 [B] setFont("Courier", size:16.0); // Courier 16.0 setFont("Courier", bold:true, size:18.0); // Courier 18.0 [B] setGray関数は引数を省略できるが、引数の順番は固定されている。 setGray() // Gray=255, Alpha=1.0 setGray(240) // Gray=240, Alpha=1.0 setGray(128,0.5) // Gray=128, Alpha=0.5 -デフォルト値を持つ変数は引数リストのどこにあっても構わない。ただし、それよりも後ろのデフォルト値無しの引数は必ず外部引数名をつけること。そうしないと、デフォルト値を持つ変数も省略できなくなるので。 -外部引数名を持つ複数の引数にデフォルト値が指定されているとき、指定する必要のある実引数のみを、引数リストとは異なる順番で記述できる。ただしデフォルト値のない引数と順番が前後してはいけない。 -外部引数名を持たない引数にデフォルト値が指定されているとき、ある引数から後ろ(右)をまとめて省略することはできるが、途中の引数を省略することはできない。(上のsetGray関数の例) **引数の値を処理中に変更できるようにする。 [#madf569e] Swiftでは、関数の仮引数に与えられた値は処理中には変更できない。 変更できないことを明示するためには、引数リストに let という修飾語を加えてもよい。 変更できるようにするには、引数リストに var という修飾語を加える。 func dayOfWeek(var m:Int, _ d:Int, var year y:Int = 2016) -> Int { if (m < 3 { if m < 3 { m += 12; --y; // 仮引数の値を変更している } let leap = y + y / 4 - y / 100 + y / 400; return (leap + (13 * m + 8) / 5 + d) % 7; } **関数内の関数 (ネスト関数) [#w46af0d7] その関数だけが下請けとして使う別の関数定義をネスト関数といい、関数の中に記述できる。 ネスト関数はクロージャとしての性質を持つ(変数のキャプチャ)。 func printMonth(firstDay:Int, _ days:Int) { func daystr(d:Int) -> String { if d <= 0 { return " " } else { return (d < 10 ? " \(d)" : " \(d)"); } } var d = 1 - firstDay while d <= days { var line = "" for _ in 0 ..< 7 { line += daystr(d) if ++d > days { break } } } }