Swift和Java在函數(method/方法)方面的比較

1. 函數是用來完成特定任務的獨立的代碼塊。Swift中函數的使用比Java中更靈活,在 Swift 中,能夠把函數當作別的函數的參數,也能夠從其餘函數中返回函數。函數的定義能夠寫在在其餘函數定義中,這樣能夠在嵌套函數範圍內實現功能封裝。在函數的參數值類型和返回值類型方面,Swift和Java函數的用法是類似的。swift

2. 函數的申明和調用數組

Swift:函數

func sayHelloAgain(personName: String) -> String {
    return "Hello again, " + personName + "!"
}
print(sayHelloAgain("Anna"))
// prints "Hello again, Anna!"

函數以 func 做爲前綴。指定函數返回類型時,用返回箭頭 ->(一個連字符後跟一個右尖括號)後跟返回類型的名稱的方式來表示。spa

Java:code

public String sayHello(String personName){
        return "hello, "+personName;
    }
System.out.println(sayHello("morden"));

3. 函數參數與返回值(Function Parameters and Return Values)blog

3.1 多重輸入參數(Multiple Input Parameters)three

Swift:生命週期

func halfOpenRangeLength(start:Int, end:Int)->Int{
            return end - start
        }

Java:ip

public int halfOpenRangeLength(int start, int end){
        return end - start;
    }

3.2 無參函數(Functions Without Parameters)字符串

Swift:

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

Java:

public String sayHelloWorld(){
        return "hello world";
    }

3.3 無返回值函數(Functions Without Return Values)

Swift:

func sayGoodbye(personName:String){
            print("GoodBye, \(personName)")
        }

Java:

public void sayGoodbye(String personName){
        System.out.println("Goodbye, "+personName);
    }

注意:在返回值方面,Swift比Java語法靈活多了,看下面代碼

func printAndCount(stringToPrint: String) -> Int {
    print(stringToPrint)
    return stringToPrint.characters.count
}
func printWithoutCounting(stringToPrint: String) {
    printAndCount(stringToPrint)
}
printAndCount("hello, world")
// prints "hello, world" and returns a value of 12
printWithoutCounting("hello, world")
// prints "hello, world" but does not return a value

第一個函數 printAndCount,輸出一個字符串並返回 Int 類型的字符數。第二個函數printWithoutCounting調用了第一個函數,可是忽略了它的返回值。

3.4 多重返回值函數(Functions with Multiple Return Values)

func count(string: String) -> (vowels: Int, consonants: Int, others: Int) {
            var vowels = 0, consonants = 0, others = 0
            for character in string.characters {
                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)
        }
    

這個例子中,count 函數用來計算一個字符串中元音,輔音和其餘字母的個數(基於美式英語的標準)。

let total = count("some arbitrary string!")
print("\(total.vowels) vowels and \(total.consonants) consonants")
// prints "6 vowels and 13 consonants"

4. 外部參數名(External Parameter Names)

若是你但願函數的使用者在調用函數時提供參數名字,那就須要給每一個參數除了局部參數名外再定義一個外部參數名。外部參數名寫在局部參數名以前,用空格分隔。外部參數名函數格式以下:

func someFunction(externalParameterName localParameterName: Int) {
    // function body goes here, and can use localParameterName
    // to refer to the argument value for that parameter
}

Swift代碼以下:

func join(string s1 : String, toString s2 : String, withJoiner joiner: String)->String{
        return s1 + joiner + s2
    }
//調用函數 let temp
= join(string: "hello", toString: "world", withJoiner: ", ") print(temp)

默認參數值(Default Parameter Values).你能夠在函數體中爲每一個參數定義默認值。當默認值被定義後,調用這個函數時能夠忽略這個參數。代碼以下:

func join(string s1: String, toString s2: String, withJoiner joiner: String = " ") -> String {
    return s1 + joiner + s2
}

像第一個版本的 join 函數同樣,若是 joiner 被賦值時,函數將使用這個字符串值來鏈接兩個字符串:

join(string: "hello", toString: "world", withJoiner: "-")
// returns "hello-world"

當這個函數被調用時,若是 joiner 的值沒有被指定,函數會使用默認值(" "):

join(string: "hello", toString:"world")
// returns "hello world"

5. 可變參數(Variadic Parameters)

一個可變參數(variadic parameter)能夠接受一個或多個值。函數調用時,你能夠用可變參數來傳入不肯定數量的輸入參數。經過在變量類型名後面加入(...)的方式來定義可變參數。傳入可變參數的值在函數體內當作這個類型的一個數組。代碼以下:

func arithmeticMean(numbers:Double...){
            var total : Double = 0
            for item in numbers{
                total += item
            }
            print("total is \(total)")
        }
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8, 19)
// returns 10.0, which is the arithmetic mean of these three numbers

注意:一個函數至多能有一個可變參數,並且它必須是參數表中最後的一個。這樣作是爲了不函數調用時出現歧義。若是函數有一個或多個帶默認值的參數,並且還有一個可變參數,那麼把可變參數放在參數表的最後。

6.常量參數和變量參數(Constant and Variable Parameters)

函數參數默認是常量。試圖在函數體中更改參數值將會致使編譯錯誤。這意味着你不能錯誤地更改參數值。可是,有時候,若是函數中有傳入參數的變量值副本將是頗有用的。你能夠經過指定一個或多個參數爲變量參數,從而避免本身在函數中定義新的變量。變量參數不是常量,你能夠在函數中把它當作新的可修改副原本使用。經過在參數名前加關鍵字 var 來定義變量參數:

func alignRight(var string : String, count : Int, pad : Character)->String{
            let amountToPad = count - string.characters.count
            if amountToPad < 1 {
                return string
            }
            let padString = String(pad)
            for _ in 1...amountToPad {
                string = padString + string
            }
            return string
        }
let originalString = "hello"
let paddedString = alignRight(originalString, 10, "-")
// paddedString is equal to "-----hello"
// originalString is still equal to "hello"

注意: 對變量參數所進行的修改在函數調用結束後便消失了,而且對於函數體外是不可見的。變量參數僅僅存在於函數調用的生命週期中。

7. 輸入輸出參數(In-Out Parameters)

      變量參數,僅僅能在函數體內被更改。若是你想要一個函數能夠修改參數的值,而且想要在這些修改在函數調用結束後仍然存在,那麼就應該把這個參數定義爲輸入輸出參數(In-Out Parameters)。定義一個輸入輸出參數時,在參數定義前加 inout 關鍵字。一個輸入輸出參數有傳入函數的值,這個值被函數修改,而後被傳出函數,替換原來的值。你只能將變量做爲輸入輸出參數。你不能傳入常量或者字面量(literal value),由於這些量是不能被修改的。當傳入的參數做爲輸入輸出參數時,須要在參數前加&,表示這個值能夠被函數修改。注意: 輸入輸出參數不能有默認值,並且可變參數不能用 inout 標記。若是你用 inout 標記一個參數,這個參數不能被 var 者 let 標記。

func swapTwoInts(inout a: Int, inout b: Int) {
    let temporaryA = a
    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)")
// prints "someInt is now 107, and anotherInt is now 3」

從上面這個例子中,咱們能夠看到 someInt 和 anotherInt 的原始值在 swapTwoInts 函數中被修改,儘管它們的定義在函數體外。注意: 輸入輸出參數和返回值是不同的。上面的 swapTwoInts 函數並無定義任何返回值,但仍然修改了 someInt 和 anotherInt 的值。輸入輸出參數是函數對函數體外產生影響的另外一種方式。

8. 函數類型(Function Types

函數類型(Function Types:每一個函數都有種特定的函數類型,由函數的參數類型和返回類型組成。

 8.1 申明函數類型,代碼以下:

func addTwoInts(a: Int, b: Int) -> Int {
    return a + b
}
func multiplyTwoInts(a: Int, b: Int) -> Int {
    return a * b
}

8.2 使用函數類型(Using Function Types),代碼以下:

var mathFunction: (Int, Int) -> Int = addTwoInts
print("Result: \(mathFunction(2, 3))")
// prints "Result: 5"
mathFunction = multiplyTwoInts
print("Result: \(mathFunction(2, 3))")
// prints "Result: 6"

8.3 函數類型做爲參數類型(Function Types as Parameter Types):你能夠用(Int, Int) -> Int這樣的函數類型做爲另外一個函數的參數類型。這樣你能夠將函數的一部分實現交由給函數的調用者。代碼以下:

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

8.4 函數類型做爲返回類型(Function Type as Return Types)

咱們能夠用函數類型做爲另外一個函數的返回類型。須要作的是在返回箭頭(->)後寫一個完整的函數類型。下面的這個例子中定義了兩個簡單函數,分別是 stepForward 和stepBackwardstepForward 函數返回一個比輸入值大一的值。stepBackward 函數返回一個比輸入值小一的值。這兩個函數的類型都是 (Int) -> Int:代碼以下:

func stepForward(input: Int) -> Int {
    return input + 1
}
func stepBackward(input: Int) -> Int {
    return input - 1
}

chooseStepFunction 根據布爾值 backwards 來返回 stepForward 函數或 stepBackward 函數:代碼以下:

func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    return backwards ? stepBackward : stepForward
}

如今能夠用 chooseStepFunction 來得到一個函數,不論是那個方向:

var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero now refers to the stepBackward() function

這個例子中計算出從 currentValue 逐漸接近到0是須要向正數走仍是向負數走。currentValue 的初始值是3,這意味着 currentValue > 0 是真的(true),這將使得 chooseStepFunction 返回stepBackward 函數。一個指向返回的函數的引用保存在了 moveNearerToZero 常量中。

8.5 嵌套函數(Nested Functions)

你所見到的全部函數都叫全局函數(global functions),它們定義在全局域中。你也能夠把函數定義在別的函數體中,稱做嵌套函數(nested functions)。默認狀況下,嵌套函數是對外界不可見的,可是能夠被他們封閉函數(enclosing function)來調用。一個封閉函數也能夠返回它的某一個嵌套函數,使得這個函數能夠在其餘域中被使用。你能夠用返回嵌套函數的方式重寫 chooseStepFunction 函數:

    func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
        func stepForward(input: Int) -> Int { return input + 1 }
        func stepBackward(input: Int) -> Int { return input - 1 }
        return backwards ? stepForward : stepBackward
    }

    @IBAction func Test(sender: AnyObject) {
        var currentValue = -4
        let moveNearerToZero = chooseStepFunction(currentValue < 0)
        // moveNearerToZero now refers to the nested stepForward() function
        while currentValue != 0 {
            print("\(currentValue)... ")
            currentValue = moveNearerToZero(currentValue)
        }
    }
// -4... // -3... // -2... // -1...
相關文章
相關標籤/搜索