天天看點

6.函數

  函數是用來完成特定任務的獨立的代碼塊。

  Swift 統一的函數文法足夠靈活,可以用來表示任何函數,包括從最簡單的沒有參數名字的 C 風格函數,到複雜的帶局部和外部參數名的 Objective-C 風格函數。參數可以提供預設值,以簡化函數調用。參數也可以既當做傳入參數,也當做傳出參數,也就是說,一旦函數執行結束,傳入的參數值可以被修改。 

1.函數定義與調用

//函數定義
func sayHello(personName: String) -> String
{
    return "Hello " + personName + "!";
}
 //函數調用
print(sayHello("Anna"));      

2.函數參數與傳回值

//1.無參函數:函數可以沒有參數
func sayHelloWorld() -> String
{
    return "hello, world";
}

//2.多參數函數:函數可以有多種輸入參數,這些參數被包含在函數的括号之中,以逗号分隔。
func sayHello(personName: String, alreadyGreeted: Bool) -> String
{
    return "hello, world";
}

//3.無傳回值函數:函數可以沒有傳回值。沒有定義傳回類型的函數會傳回特殊的值,叫 Void。它其實是一個空的元組,沒有任何元素,可以寫成()。
func sayGoodbye(personName: String) //->()
{
    print("Goodbye, \(personName)!");
}

//4.多重傳回值函數:可以用元組類型讓多個值作為一個複合值從函數中傳回。
func minMax(array: [Int]) -> (min: Int, max: Int)
{
    return (2, 3);
}

//5.可選元組傳回類型:可以使用可選的元組傳回類型反映整個元組可以是nil的事實。
func minMax2(array: [Int]) -> (min: Int, max: Int)?
{
    if array.isEmpty
    {
        return nil;
    }
    
    return (2, 3);
}      

3.函數參數名稱

  • 函數參數都有一個外部參數名和一個局部參數名。外部參數名用于在函數調用時标注傳遞給函數的參數,局部參數名在函數的實作内部使用。這個和OC比較類似,例如OC中的如下方法:
//numberOfRowsInSection可了解為外部參數名,section為内部參數名
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

}      
  • 一般情況下,第一個參數省略其外部參數名,第二個以及随後的參數使用其局部參數名作為外部參數名。所有參數必須有獨一無二的局部參數名。盡管多個參數可以有相同的外部參數名,但不同的外部參數名能讓你的代碼更有可讀性。
//1.指定外部參數名:在局部參數名前指定外部參數名,中間以空格分隔
func someFunction(externalParameterName localParameterName: Int)
{
    
}
//如果提供了外部參數名,那麼函數在被調用時,必須使用外部參數名。思考:如果沒有指定外部參數名,調用時能不能把内部參數名當外部參數名使用?(第一個參數如果沒有外部參數名是不能寫的,第二個參數必須寫)
someFunction(externalParameterName: 2);  //正确
//someFunction(2);  //錯誤

//2.忽略外部參數名:如果不想為第二個及後續的參數設定外部參數名,用一個下劃線(_)代替一個明确的參數名。第一個參數預設忽略其外部參數名稱,顯式地寫下劃線是多餘的。
func someFunction(firstParameterName: Int, _ secondParameterName: Int)
{
    
}
someFunction(1, 2);

//3.預設參數值:可以在函數體中為每個參數定義預設值。當預設值被定義後,調用這個函數時可以忽略這個參數。
//将帶有預設值的參數放在函數參數清單的最後。這樣可以保證在函數調用時,非預設參數的順序是一緻的,同時使得相同的函數在不同情況下調用時顯得更為清晰。
func someFunction(parameterWithDefault: Int = 12, param : String)
{
    print("\(param) \(parameterWithDefault)");
}
someFunction(6, param: "Hello");
someFunction(param : "Hello");

//4.可變參數:通過在變量類型名後面加入(...)的方式來定義可變參數。
//一個函數最多隻能有一個可變參數
func arithmeticMean(numbers: Double...)
{
    var total: Double = 0;
    for number in numbers
    {
        total += number;
    }
    print("\(total)");
}
arithmeticMean(3, 4, 5)
arithmeticMean(2, 3, 4);

//5.常量參數和變量參數:函數參數預設是常量。試圖在函數體中更改參數值将會導緻編譯錯誤。
//通過在參數名前加關鍵字 var 來定義變量參數(這個将在Swift 3中廢棄,是以不需要關注)
//func alignRight(var string: String, totalLength: Int, pad: Character)
//{
//
//}

//6.輸入輸出參數:變量參數,僅僅能在函數體内被更改。如果想要一個函數可以修改參數的值,并且想要在這些修改在函數調用結束後仍然存在,那麼就應該把這個參數定義為輸入輸出參數
//定義一個輸入輸出參數時,在參數定義前加 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);
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)");      

4.函數類型

  • 由函數的參數類型和傳回類型組成。
//1.函數類型是 (Int, Int) -> Int
func addTwoInts(a: Int, _ b: Int) -> Int
{
    return a + b;
}

func multiplyTwoInts(a: Int, _ b: Int) -> Int
{
    return a * b;
}

var mathFunction: (Int, Int) -> Int = addTwoInts;
print("Result: \(mathFunction(2, 3))");

//2.函數類型作為參數類型
func printMathResult(mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int)
{
    print("Result: \(mathFunction(a, b))");
}
printMathResult(addTwoInts, 3, 5);

//3.函數類型作為傳回類型
func chooseFunction(isAdd: Bool) -> (Int, Int) -> Int
{
    return isAdd ? addTwoInts : multiplyTwoInts;
}
let selFunc = chooseFunction(true);
selFunc(2, 3);      

5.嵌套函數

  • 嵌套函數是對外界不可見的,但是可以被它們的外圍函數調用。一個外圍函數也可以傳回它的某一個嵌套函數,使得這個函數可以在其他域中被使用。 
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);
while currentValue != 0
{
    print("\(currentValue)... ");
    currentValue = moveNearerToZero(currentValue);
}
print("zero!");      

無善無惡心之體,

有善有惡意之動,

知善知惡是良知,

為善去惡是格物。

下一篇: 8.枚舉

繼續閱讀