swift(6)関数


Cとは異なり、元の戻り値が書かれている場所にはキーワードfunが使用され、関数の先頭を定義します.パラメータ部分は同じタイプに変数名を付けますが、位置が入れ替わり、複数のコロンがあり、戻り値は矢印と戻り値タイプで表されます.
//               
func sayHello(personName: String) -> String {
    let greeting = "Hello, " + personName + "!"
    return greeting
}
//        
println(sayHello("Anna"))

//               
func halfOpenRangeLength(start: Int, end: Int) -> Int {
    return end - start
}
//    C  ,
println(halfOpenRangeLength(1, 10))

//            
func sayHelloWorld() -> String {
    return "hello, world"
}
println(sayHelloWorld())

//             , C  ,      void,     ()
func sayGoodbye(personName: String) {
    println("Goodbye, \(personName)!")
}
sayGoodbye("Dave")

Cと同様に,戻り値があっても無視されて使用されない.同様に、関数名の後に戻り値が定義されている場合は、関数体にreturn文が必要です.そうしないと、レポートのコンパイルエラーが発生します.
関数には複数の戻り値があり、メタグループを使用して実装できます.
func count(string: String) -> (vowels: Int, consonants: Int, others: Int) {
    var vowels = 0, consonants = 0, others = 0
    for character in string {
        switch String(character).lowercaseString {
        case "a", "e", "i", "o", "u":
            ++vowels
        case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
        "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
            ++consonants
        default:
            ++others
        }
    }
    return (vowels, consonants, others)
}

//    
let total = count("some arbitrary string!")
println("\(total.vowels) vowels and \(total.consonants) consonants")

関数のパラメータは拡張子を指定することができ、呼び出し時に各パラメータの意味を知ることができ、OCの特徴を継続することができる.
//               
func join(string s1: String, toString s2: String, withJoiner joiner: String)
    -> String {
        return s1 + joiner + s2
}
//         
join(string: "hello", toString: "world", withJoiner: ", ")

ただし、2つのパラメータ名を書くのは面倒ですが、パラメータ名が拡張パラメータ名として十分に明確であれば、次のように関数を定義できます.
func join(#string: String, #toString: String, #withJoiner: String)
    -> String {
        return string+ withJoiner+ toString
}
//         
join(string: "hello", toString: "world", withJoiner: ", ")

パラメータのデフォルト値の書き方、パラメータ定義のタイプの後で値を割り当てます
func join(string s1: String, toString s2: String, withJoiner joiner: String = " ") -> String {
        return s1 + joiner + s2
}

パラメータにデフォルト値がある場合は、パラメータ拡張子が書かれていなくても、デフォルト値のあるパラメータ名は拡張子として使用できます.
func join(s1: String, s2: String, joiner: String = " ") -> String {
    return s1 + joiner + s2
}
//       joiner       
join("hello", "world", joiner: "-")

Cと似ていて...不確定なパラメータの個数を表す場合
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)

swift関数のパラメータのデフォルトはletタイプ、すなわちデフォルトは変更できません.関数内でパラメータを変更するには、パラメータの前にvarを追加する必要があります.
func alignRight(var string: String, count: Int, pad: Character) -> String {
    let amountToPad = count - countElements(string)
    for _ in 1...amountToPad {
        string = pad + string
    }
    return string
}
let originalString = "hello"
let paddedString = alignRight(originalString, 10, "-")
//paddedString    "-----hello"
//  originalString    "hello",      

伝入伝出パラメータ、パラメータの前にinoutキーワードを使用して、伝入伝出パラメータにデフォルト値があってはいけなくて、varとletに修飾されてはいけなくて、数のパラメータを不定にします...inoutで修飾することはできません.呼び出し関数は、転送パラメータに&接頭辞を使用します.この変数が変更される可能性があり、転送パラメータが定数ではないことを示します.
func swapTwoInts(inout a: Int, inout b: Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
//         ,     C         。

関数は、パラメータタイプとして、戻り値タイプとして、他の変数に値を割り当てることができます.
func addTwoInts(a: Int, b: Int) -> Int {
    return a + b
}
func multiplyTwoInts(a: Int, b: Int) -> Int {
    return a * b
}
//            (Int, Int) -> Int,                 。               
var mathFunction: (Int, Int) -> Int = addTwoInts
//      mathFunction  addTwoInts,      2 3  , 5
println("Result: \(mathFunction(2, 3))")
//         ,       
let anotherMathFunction = addTwoInts

//             
func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) {
    println("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)

関数タイプを戻り値タイプとして使用
func stepForward(input: Int) -> Int {
    return input + 1
}
func stepBackward(input: Int) -> Int {
    return input - 1
}
//  bool   +1     -1   ,      (Int) -> Int,          
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    return backwards ? stepBackward : stepForward
}
//    ,moveNearerToZero    (Int) -> Int      ,      stepBackward()
var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0)

関数のネスト、関数の内部定義
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    func stepForward(input: Int) -> Int { return input + 1 }
    func stepBackward(input: Int) -> Int { return input - 1 }
    return backwards ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero now refers to the nested stepForward() function
while currentValue != 0 {
    println("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
println("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!