Swift Functions メモ
The Swift Programming LanguageのFunctionsセクションのメモ。
関数の定義
Swiftの関数はfuncキーワードから始まり、次のように書く。
func function_name(parameters) -> return_type { // 関数ボディ return return_value }
文字列personNameを受け取り"Hello, personName!"を返すsayHello関数は以下のようになる。
func sayHello (personName: String) -> String { return "Hello, \(personName)!" } sayHello("Anna") // playgroundでの出力結果:Hello, Anna!
複数のパラメータを渡す場合はカンマで区切る。
func substract(a: Int, b: Int) -> Int { return b - a } substract(3, 1) // 出力:2
パラメータを必要としない場合は省略できる。
func sayHelloWorld() -> String { return "Hello, world" } sayHelloWorld() // 出力:Hello, world
戻り値がない場合は -> return_type の部分を省略することができる。
func sayGoodbye() { println("Goodbye") } sayGoodbye() // 出力結果:Goodbye
※戻り値がない関数は実際にはVoid型が返る。
Void空タプルで定義されている。
typealias Void = ()
呼び出した関数の戻り値は関数の中では無視される。
func printAndCount(stringToPrint: String) -> Int { println(stringToPrint) // countElements:文字数を取得する関数 return countElements(stringToPrint) } func printWithoutCounting(stringToPrint: String) { printAndCount(stringToPrint) // 戻り値は無視される } printWithoutCounting("hello, world") // 出力:"hello, world" (戻り値はない)
タプル型を利用して、複数の値を返すこともできる。
func seperateFirstAndLastName(fullName: String) -> (firstName: String, lastName: String) { let firstAndLastName = fullName.componentsSeparatedByString(" ") return (firstAndLastName[0], firstAndLastName[1]) } let fullName = seperateFirstAndLastName("Joe Black") fullName.firstName // 出力:Joe fullName.lastName // 出力:Black
関数のパラメータ
swiftでは外部パラメータ名、デフォルトパラメータ値、可変長引数、In-Outパラメータなどの機能がある。
外部パラメータ名(External Parameter Names)
上記の関数のパラメータは全てローカルパラメータと呼ばれ、関数内部からしか使用できない。外部パラメータ名はローカルパラメータの前に宣言する。
func myFunction(externalParameterName localParameterName: Int) {
// 関数ボディ
}
下の関数は文字列joinerでs1とs2を結合する。
// 通常の書き方 func join(s1: String, s2: String, joiner:String) -> String{ return s1 + joiner + s2 } // 外部パラメータ名を使った書き方 func join(string s1: String, toString s2: String, withJoiner joiner: String) -> String { return s1 + joiner + s2 }
関数のボディは同じだが、呼び出し方が違う。
// 通常の書き方 join("hello", "world", ", ") // 外部引数名を使った書き方 join(string: "hello", toString: "world", withJoiner: ", ")
引数の目的が不明瞭な場合は、外部パラメータ名を使用することで可読性を高めることが目的のようだ。ローカルパラメータ名がすでに外部パラメータとして最適な場合は#を使用して2つの名前を同じにできる。
func containsCharacter(#string: String, #characterToFind: Character) -> Bool { for character in string { if (character == characterToFind) { return true } } return false } containsCharacter(string: "abcdedefg", characterToFind: "g") // 出力:true
デフォルト引数
swiftではデフォルト引数を与えることができる。デフォルト値を与える場合、パラメータの最後に書く。例えば、join関数のjoinerにデフォルト値(スペース)を与えた場合、以下のようになる。
func join(string s1: String, toString s2: String, withJoiner joiner: String = " ") -> String { return s1 + joiner + s2 } // デフォルト値を使用した呼び出し方 join(string: "hello", toString: "world") // 出力:hello world
デフォルト値を持つパラメータは自動でローカルパラメータ名と同じ外部パラメータ名が与えられる。つまりjoinは以下のように書ける。
func join(s1: String, s2: String, joiner: String = " ") -> String { return s1 + joiner + s2 } // デフォルト値を使用した呼び出し方 join("hello", "world", joiner: ", ") // 出力:hello, world
※自動で外部パラメータ名が与えられる機能をオフにする場合は、アンダースコア(_)をローカルパラメータ名の前につけることで解除することができる。
func join(s1: String, s2: String, _ joiner: String = " ") -> String { return s1 + joiner + s2 } // デフォルト値を使用した呼び出し方 join("hello", "world", joiner: ", ") // 外部パラメータがないのでコンパイルエラーになる
可変長パラメータ
任意の数の引数を取る場合は、パラメータの型の後にドット3つ(...)で宣言する。可変長パラメータはパラメータの最後にしか宣言ができないので、関数は最大で1つの可変長パラメータをもつ。
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) // 出力:3.0
関数のセクションは意外とボリュームがある・・・;
残りの部分は続編を書くことにします。