/*
函數的定義與調用
*/
//下面例子中的函數的名字是 greet(person:) ,之所以叫這個名字,是因為這個函數用一個人的名字當做輸入,并 返回向這個人問候的語句。為了完成這個任務,你需要定義一個輸入參數——一個叫做 person 的 String 值,和一個包含給這個人問候語的 String 類型的返回值:
func greet(person:String) -> String{
let greeting = "Hello," + person + "!"
return greeting
}
var sddd:String = greet(person: "asas");
print(greet(person: "asas"))
func greetAgain(person: String) -> String {
return "Hello again, " + person + "!"
}
print(greetAgain(person: "Anna")) // 打印 "Hello again, Anna!"
//函數參數與返回值
//無參數函數
func sayHelloWorld() -> String {
return "hello, world"
}
print(sayHelloWorld()) // 打印 "hello, world"
//多參數函數
func greets(person:String , alreadyGreeted:Bool) -> String {
if alreadyGreeted {
return greetAgain(person:person)
}else{
return greet(person: person)
}
}
print(greets(person: "Tim", alreadyGreeted:true))
// 打印 "Hello again, Tim!"
//無返回值參數
func greet2(person: String) {
print("Hello, \(person)!")
}
greet2(person: "Dave") // 打印 "Hello, Dave!"
//因為這個函數不需要返回值,所以這個函數的定義中沒有返回箭頭(->)和返回類型。
//被調用時,一個函數的返回值可以被忽略:
func printAndCount(string: String) -> Int {
print(string)
return string.characters.count
}
func printWithoutCounting(string: String) {
let _ = printAndCount(string: string)
}
printAndCount(string: "hello, world")
// 打印 "hello, world" 并且返回值 12 printWithoutCounting(string: "hello, world") // 打印 "hello, world" 但是沒有返回任何值
//多重返回值函數
//你可以用元祖(tuple)類型讓多個值作為一個符合值從函數中返回,下例中定義了一個名為 minMax(array:) 的函數,作用是在一個 Int 類型的數組中找出最小值與最大值。
func minMax(array:[NSInteger]) -> (min: NSInteger,max: NSInteger) {
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);
}
var bounds = minMax(array: [8, -6, 2, 109, 3, 71])
print("min is \(bounds.min) and max is \(bounds.max)")
//可選元祖返回類型
func minMax2(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)
}
//使用可選綁定來檢查 minMax(array:) 函數返回的是一個存在的元組值還是 nil :
if let bounds = minMax2(array: [8, -6, 2, 109, 3, 71]) {
print("min is \(bounds.min) and max is \(bounds.max)")
}
//函數參數標簽和參數名稱
func someFunction(firstParameterName: Int, secondParameterName: Int) {
// 在函數體內,firstParameterName 和 secondParameterName 代表參數中的第一個和第二個參數值
}
someFunction(firstParameterName: 1, secondParameterName: 2)
//指定參數標簽
func someFunction2(argumentLabel parameterName: Int) {
// 在函數體內,parameterName 代表參數值
}
//這個版本的 greet(person:) 函數,接收一個人的名字和他的家鄉,并且返回一句問候:
func greet3(person: String, from hometown: String) -> String {
return "Hello \(person)! Glad you could visit from \(hometown)."
}
print(greet3(person: "Bill", from: "Cupertino"))
// 打印 "Hello Bill! Glad you could visit from Cupertino."
//忽略參數標簽
//如果你不希望為某個參數添加一個標簽,可以使用一個下劃線( _ )來代替一個明確的參數標簽。
func someFunction3(_ firstParameterName: Int, secondParameterName: Int) {
// 在函數體內,firstParameterName 和 secondParameterName 代表參數中的第一個和第二個參數值
}
someFunction3(1, secondParameterName: 2)
//默認參數值
func someFunction4(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {
// 如果你在調用時候不傳第二個參數,parameterWithDefault 會值為 12 傳入到函數體中。
}
someFunction4(parameterWithoutDefault: 3, parameterWithDefault: 6) // parameterWithDefault = 6
someFunction4(parameterWithoutDefault: 4) // parameterWithDefault = 12
//可變參數:
//一個可變參數(variadic parameter)可以接受零個或多個值。函數調用時,你可以用可變參數來指定函數參數 可以被傳入不確定數量的輸入值。通過在變量類型名后面加入( ... )的方式來定義可變參數。
func arithmeticMean(_ numbers:Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
print( arithmeticMean(1,2,3,4,5))
//輸入輸出參數,定義一個輸入輸出參數時,在參數定義前加 inout 關鍵字。一個輸入輸出參數有傳入函數的值,這個值被函數 修改,然后被傳出函數,替換原來的值。你只能傳遞變量給輸入輸出參數。你不能傳入常量或者字面量,因為這些量是不能被修改的。當傳入的參數作為輸入輸出參數時,需要在參數名前加&符,表示這個值可以被函數修改。
//函數參數默認是常量。下例中,(_:_:)函數有兩個分別叫做a和b的輸入輸出參數:
func swapTwoInts(_ a: inout NSInteger, _ b: inout NSInteger) {
let temporaryA = 0
a = b
b = temporaryA
}
//你可以用兩個int型的變量來調用swapTwoInts(_:_:)。需要注意的是,someInt和anotherInt在傳入swapTwoInts(_:_:)函數前,都加了&的前綴:
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)") // 打印 "someInt is now 107, and anotherInt is now 3"
//函數類型:
//函數類型由函數的參數類型和返回類型組成
func addTwoInts(_ a:NSInteger,_ b:NSInteger) -> NSInteger {
return a + b
}
func multiplyTwoInts(_ a: Int, _ b: Int) -> Int {
return a * b
}
//沒有參數,沒有返回值的函數
func printHelloWorld() {
print("hello world")
}
//使用函數的類型
var mathFunction:(NSInteger,NSInteger) -> NSInteger = addTwoInts
print("Resualt: \(mathFunction(2,3))")
//有相同匹配類型的不同函數可以被賦值給同一個變量,就像非函數類型的變量一樣:
mathFunction = multiplyTwoInts
print("Result: \(mathFunction(2, 3))")
// Prints "Result: 6"
//函數類型作為參數類型
//你可以用(Int,Int) ->Int 這樣的函數類型作為另一個函數的參數類型,這樣可以將函數的一部分實現留給函數的調用者來提供
func printMathResult(_ mathFunction:(NSInteger,NSInteger) -> NSInteger , _ a:NSInteger , _ b:NSInteger) {
print("resault: \(mathFunction(a,b))")
}
print(printMathResult(addTwoInts, 3, 5))
//函數作為返回值類型
//你可以用函數類型作為另一個函數的返回類型。你需要做的是在返回箭頭(->)后寫一個完整的函數類型。
func stepForward(_ input:NSInteger) -> NSInteger {
return input + 1
}
func stepBackword(_ input: NSInteger) -> NSInteger {
return input - 1
}
func chooseStepFunction(backword: Bool) -> (NSInteger) -> NSInteger {
return backword ? stepBackword : stepForward
}
var currentValue = 3
let moveNearerZero = chooseStepFunction(backword: currentValue > 0)
print(moveNearerZero)
while currentValue != 0 {
print("\(currentValue)...")
currentValue = moveNearerZero(currentValue)
}
//嵌套函數
//默認情況下嵌套函數是對外界不可見得,但是可以被他們的外圍函數調用。一個外圍函數也可以返回它的某一個嵌套函數,使得這個函數可以在其他域中被使用
//用返回嵌套函數的方式重寫 chooseStepFunction(backward:) 函數:
func chooseStepFunctions(backword: Bool) -> (NSInteger) -> NSInteger {
func stepForward(input: NSInteger) -> NSInteger {
return input + 1
}
func stepBackword(input: NSInteger) -> NSInteger {
return input - 1
}
return backword ? stepBackword : stepForward
}
var currentValue2 = -4
let moveNearerToZero = chooseStepFunctions(backword: currentValue2 > 0)
// moveNearerToZero now refers to the nested stepForward() function
while currentValue2 != 0 {
print("\(currentValue2)... ")
currentValue2 = moveNearerToZero(currentValue2)
}