【Swift學習】Swift編程之旅---函數(十)

来源:http://www.cnblogs.com/salam/archive/2016/04/24/5410984.html
-Advertisement-
Play Games

函數是一組用於執行特定任務的獨立的代碼段,你用一個名字來標識函數,這個名字是用來“調用”函數來執行它的任務。 swift統一函數的語法具有足夠的靈活性來表達任何一個簡單的不帶參數的名稱與本地和外部的每個參數的參數名稱的複雜objective-c-style C風格的函數方法。參數可以提供預設值,以簡 ...


  函數是一組用於執行特定任務的獨立的代碼段,你用一個名字來標識函數,這個名字是用來“調用”函數來執行它的任務。

  swift統一函數的語法具有足夠的靈活性來表達任何一個簡單的不帶參數的名稱與本地和外部的每個參數的參數名稱的複雜objective-c-style C風格的函數方法。參數可以提供預設值,以簡化函數調用,並且可以通過在輸出參數中,一旦該功能完成了它的執行,它就可以修改傳遞的變數

  swift每一個函數都有一個類型,由形參類型和返回類型組成。你可以使用這種類型的任何其他類型,這使得它很容易將函數作為參數的其他函數,並返回函數的函數。函數還可以用其他函數來封裝在嵌套函數作用域內的有用函數。

 

  定義和調用函數

func sayHello(personName: String) -> String {
    let greeting = "Hello, " + personName + "!"
    return greeting
}

 

print(sayHello("Anna"))
// Prints "Hello, Anna!"
print(sayHello("Brian"))
// Prints "Hello, Brian!

 

sayHello是函數的名稱,personName是它的參數,類型是String,返回一個String類型的數據,使用->符號來標識函數的返回類型,後面是函數的返回類型。

 

  函數的形參和返回值

  函數參數和返回值是非常靈活的。您可以從一個簡單的實用程式函數中定義任何一個簡單的函數,用一個未命名的參數來定義一個複雜的函數。

 

  無參函數

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

 

 

  多參函數

func sayHello(personName: String, alreadyGreeted: Bool) -> String {
    if alreadyGreeted {
        return sayHelloAgain(personName)
    } else {
        return sayHello(personName)
    }
}
print(sayHello("Tim", alreadyGreeted: true))
// Prints "Hello again, Tim!

 

  

  無返回值函數(實際返回void)

func sayGoodbye(personName: String) {
    print("Goodbye, \(personName)!")
}
sayGoodbye("Dave")
// Prints "Goodbye, Dave!

 

  

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

 

 

  多返回值函數

func minMax(array: [Int]) -> (min: Int, max: Int) {
    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)
}

 

let bounds = minMax([8, -6, 2, 109, 3, 71])
print("min is \(bounds.min) and max is \(bounds.max)")
// Prints "min is -6 and max is 109

 

   函數形參名

   函數的形參包括本地和外部參數名。外部參數名稱用於將參數傳遞給函數調用。函數的實現中使用了局部參數名稱

func someFunction(firstParameterName: Int, secondParameterName: Int) {
    // function body goes here
    // firstParameterName and secondParameterName refer to
    // the argument values for the first and second parameters
}
someFunction(1, secondParameterName: 2)

 

 

  預設形參值

  您可以在參數類型之後給任何的參數設置一個預設值,如果您設置了預設值,那麼就可以在調用該函數時忽略此參數。

func someFunction(parameterWithDefault: Int = 12) {
    // function body goes here
    // if no arguments are passed to the function call,
    // value of parameterWithDefault is 12
}
someFunction(6) // parameterWithDefault is 6
someFunction() // parameterWithDefault is 12

 

在函數的參數列表的結尾處設置預設值

 

  可變參數

  一個可變的參數接受特定類型的零個或多個值。當函數被調用時,你使用一個可變的參數可以傳入不同數量的指定類型的參數,在參數類型名稱後面插入...來實現可變參數。函數體的可變參數值被當做一個特定類型的數組來處理。例子如下

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)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8.25, 18.75)
// returns 10.0, which is the arithmetic mean of these three numbers

  numbers: Double...被當做一個存放Double類型的數組,我們可以遍歷它的每一個元素

  註意:一個函數只能有一個可變參數

 

  In-Out 形參

  函數參數預設為常量,在函數體內修改參數值會發生編譯時錯誤,這意味著你不能改變一個參數的值。如果你想要一個函數來修改某個參數的值,並希望這些改變在函數調用結束後是永久的,那麼使用 in-out參數來代替

  使用inout關鍵字來定義一個in-out參數,但是參數不能為常量,只能為變數。當你調用時直接在參數名前加&符號來標識此參數可以被該函數修改。

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)")
// Prints "someInt is now 107, and anotherInt is now 3”

 

 

  函數類型

  每個函數都有一個特定的函數類型,由形參類型和函數的返回類型組成

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

 這個例子定義了addTwoInts,multiplyTwoInts2個函數,它們的類型都是(Int, Int) -> Int

func printHelloWorld() {
    print("hello, world")
}

 

它的類型是()->Void

 

  函數類型的使用

  在swift中您可以像任何其他類型一樣的使用函數類型。例如,你可以定義一個常量或變數為一個函數類型,併為變數指定一個對應的函數:

var mathFunction: (Int, Int) -> Int = addTwoInts

 

 可以解讀為:"定義一個名為mathFunction變數,該變數的類型為'一個函數,它接受兩個Int值,並返回一個Int值。'設置這個新的變數來引用名為addTwoInts函數。

該addTwoInts函數具有與mathFunction相同類型的變數,所以這個賦值能通過swift的類型檢查。

現在你可以使用mathFunction來調用指定的函數:

print("Result: \(mathFunction(2, 3))")
// Prints "Result: 5

 

與其他類型一樣,當你給函數賦一個常量或者變數時,你可以讓Swift去推斷函數的類型。    

let anotherMathFunction = addTwoInts
// anotherMathFunction is inferred to be of type (Int, Int) -> Int

 

 

  作為形參類型的函數類型

  可以使用一個函數類型,如(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

 

  

  作為返回類型的函數類型 

  你可以將一個函數類型作為另一個函數的返回類型。你可以在返回函數的返回箭頭(->) 後立即編寫一個完整的函數類型來實現。下麵的例子定義了兩個簡單的函數調用stepForward和stepBackward。stepForward函數返回一個輸入值+1的結果,而stepBackward函數返回一個輸入值-1的結果。這兩個函數都有一個相同的(Int) -> Int類型 :

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

 

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

 

 

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

 

 

print("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
    print("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// 3...
// 2...
// 1...
// zero!

 

 

  嵌套函數

  迄今為止所有你在本章中遇到函數都是全局函數,在全局作用域中定義。其實你還可以在其他函數體中定義函數,被稱為嵌套函數。嵌套函數預設對外界是隱藏的,但仍然可以通過它們包裹的函數調用和使用它。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 ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero now refers to the nested stepForward() function
while currentValue != 0 {
    print("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • title: 帶你實現開發者頭條APP(四) 首頁優化(加入design包) tags: design,Toolbar,TabLayout,RecyclerView grammar_cjkRuby: true 一 、前言 上次模仿開發者頭條首頁實現了一個版本,給 "345大神,我的產品經理" 一看, ...
  • 1、彈框出現在屏幕中間位置 此方法可以添加文本框,輸入內容 2、彈框出現在屏幕底部(兩種方式的不同點在於代碼第一行最後的,底部是UIAlertControllerStyleActionSheet) ...
  • 最近解析些複雜的節點數據解析,用安卓自帶的json解析比較麻煩所以只能用Gson解析,所以從網上下了點demo來看看 http://blog.csdn.net/tkwxty/article/details/34474501這個看看還不錯 例子代碼如下 ...
  • 給EditText追加ChangedListener可以監聽EditText內容變化的監聽 如圖是效果圖 類似於過濾的一種實現 1 佈局也就是一個EditText,當EditText內容發生變化時(當輸入數字時)就會出現一個PopupWindow通過ChangedListener來顯示監聽 2 數據 ...
  • Android開發中,常常會用到color.xml顏色配置,好的顏色配置可以讓尼的應用讓人看起來賞心悅目! 不羅嗦,上圖先 該工程已經羅列了常用的顏色配置 附上工程鏈接:http://download.csdn.net/detail/geniuseoe2012/5816967 什麼?還沒找到尼想要的 ...
  • TNW中文站 4月8日報道 安卓操作系統的軟體開發語言是Java,而在過去幾年中,有關Java的版權,谷歌(微博)和甲骨文之間發生了長期的訴訟。最新外媒消息稱,谷歌正在考慮將蘋果開發的Swift作為未來安卓軟體開發的“一級”語言,此外Facebook、Uber等公司也開始越來越重視Swift的使用。 ...
  • 字典轉模型 1> 什麼是字典轉模型? 字典數據/數組(可以是 plist 文件中的數據也可以是網路後臺的數據等)轉化為模型對象/數組. 2> 註意 模型要提供可以傳入字典參數的構造方法.(一個對象方法和一個類方法) - (instancetype)initWithDict:(NSDictionary ...
  • ➠更多技術乾貨請戳:聽雲博客 做為一個測試人員,工作中經常會用到數據抓包工具來進行數據分析和驗證,下麵就簡單介紹一下工作中常用的抓包工具。 TcpDump抓包 Tcpdump是一個用於截取網路分組,並輸出分組內容的工具。它憑藉強大的功能和靈活的截取策略,使其成為類UNIX系統下用於網路分析和問題排查 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...