函数是一组用于执行特定任务的独立的代码段,你用一个名字来标识函数,这个名字是用来“调用”函数来执行它的任务。

  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[]
var currentMax = array[]
for value in array[..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
let bounds = minMax([, -, , , , ])
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(, secondParameterName: )

  默认形参值

  您可以在参数类型之后给任何的参数设置一个默认值,如果您设置了默认值,那么就可以在调用该函数时忽略此参数。

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

在函数的参数列表的结尾处设置默认值

  可变参数

  一个可变的参数接受特定类型的零个或多个值。当函数被调用时,你使用一个可变的参数可以传入不同数量的指定类型的参数,在参数类型名称后面插入...来实现可变参数。函数体的可变参数值被当做一个特定类型的数组来处理。例子如下

func arithmeticMean(numbers: Double...) -> Double {
var total: Double =
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
arithmeticMean(, , , , )
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(, 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 =
var anotherInt =
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, , )
// Prints "Result: 8

  

  作为返回类型的函数类型 

  你可以将一个函数类型作为另一个函数的返回类型。你可以在返回函数的返回箭头(->) 后立即编写一个完整的函数类型来实现。下面的例子定义了两个简单的函数调用stepForward和stepBackward。stepForward函数返回一个输入值+1的结果,而stepBackward函数返回一个输入值-1的结果。这两个函数都有一个相同的(Int) -> Int类型 :

func stepForward(input: Int) -> Int {
return input +
}
func stepBackward(input: Int) -> Int {
return input -
}
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
return backwards ? stepBackward : stepForward
}
var currentValue =
let moveNearerToZero = chooseStepFunction(currentValue > )
// moveNearerToZero now refers to the stepBackward() function
print("Counting to zero:")
// Counting to zero:
while currentValue != {
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 + }
func stepBackward(input: Int) -> Int { return input - }
return backwards ? stepBackward : stepForward
}
var currentValue = -
let moveNearerToZero = chooseStepFunction(currentValue > )
// moveNearerToZero now refers to the nested stepForward() function
while currentValue != {
print("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!

【Swift学习】Swift编程之旅---函数(十)的更多相关文章

  1. Swift学习——Swift基础具体解释(一)

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zhenyu5211314/article/details/34807025 注:由于基础部分在Swi ...

  2. swift学习初步(四)-- 函数

    好了,让我们开始接着前几天写的系列博客开始今天的这篇博客.在swift里面如果你需要定义一个方法的话,你需要使用关键字:func,请看下面的这段代码: func sayHello(name:Strin ...

  3. Swift学习——Swift解释具体的基础(六)

    Optionals    可选 可选(它似乎并不如此翻译)它适用于那些值这种情况可能是空的,有两种情况一个可选:存在值并等于x,要么值不存在. 选配的概念在OC和C里面并没有.在OC中最接近的概念就是 ...

  4. Swift学习——Swift解释特定的基础(七)

    Implicitly Unwrapped Optionals    隐式解析选项 如上所述.可选意味着常数或变量"没有值".通过可选if声明来推断是否存在值,假设有值析值. 有时候 ...

  5. python#父与子的编程之旅#第十四章

    1. 为BankAccount 建立一个类定义.它应该有一些属性,包括账户名(一个字符串).账号(一个字符串或整数)和余额(一个浮点数),另外还要有一些方法显示余额.存钱和取钱. class Bank ...

  6. 【Swift学习】Swift编程之旅---闭包(十一)

    闭包是可以在代码中被传递和使用的自包含功能模块,它很像c和oc中的block,和.net中的lambdasbas表达式. 闭包可以捕获和存储其所在上下文中任意常量和变量的引用. 包裹着这些常量和变量的 ...

  7. swift学习笔记2——函数、闭包

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  8. swift 学习(二)基础知识 (函数,闭包,ARC,柯里化,反射)

    函数 func x(a:Int, b:Int)  {}   func x(a:Int, b:Int) -> Void {}  func x(a:Int, b:Int) ->(Int,Int ...

  9. 《从零开始学Swift》学习笔记(Day 7)——Swift 2.0中的print函数几种重载形式

    原创文章,欢迎转载.转载请注明:关东升的博客 Swift 2.0中的print函数有4种重载形式: l   print(_:).输出变量或常量到控制台,并且换行. l   print(_:_:).输出 ...

随机推荐

  1. 年底了,特贡献一些C#有意思的算法题

    2013年,即将要过去了.屌丝C#程序员们拿到了年终奖不?是不是又想蠢蠢欲动了?是不是想通过跳槽来为自己实现加薪的梦想?好吧,跳槽之前还是做点准备吧,准备好C#的笔试吧.这里我收集了些奉献给大家,大家 ...

  2. C语言结构体-struct

    知识点: 1)结构体的定义. 2)结构体的sizeof. 3)  结构体的指针. 1) 结构体的定义: 在逻辑上有一定关联的多个数据类型做为一整体进行操作的数据结构,它的关键字是struct.下面我将 ...

  3. EasyDarwin不能保存HLS列表的解决方案

    官网: easydarwin.org 安装过程 http://doc.easydarwin.org/EasyDarwin/README/ 安装客户端,iVMS-4200 客户端,并运行. 在设备管理里 ...

  4. Web Essentials之Markdown和自定义编辑器(Web Essentials完结)

    返回Web Essentials功能目录 本篇目录 功能 自定义编辑器 开源项目都会在项目的根目录放一个Readme.md文件来告诉读者一些重要的说明,那么就可以在VS中直接编辑Markdown文件. ...

  5. Java设计模式4:单例模式

    前言 非常重要,单例模式是各个Java项目中必不可少的一种设计模式.本文的关注点将重点放在单例模式的写法以及每种写法的线程安全性上.所谓"线程安全性"的意思就是保证在创建单例对象的 ...

  6. AMD加载器实现笔记(一)

    之前研究过AMD,也写过一篇关于AMD的文章<以代码爱好者角度来看AMD与CMD>.代码我是有看过的,基本的原理也都明白,但实际动手去实现却是没有的.因为今年计划的dojo教程<静静 ...

  7. 在AWS中创建NAT节点

    NAT, Network Address Translation,即网络地址转换.当内部网络的主机想要访问外网,但是又不想直接暴露给公网,可以通过NAT节点来访问外网.这样做有两个好处,第一是内网的主 ...

  8. 虚拟化平台cloudstack(3)——安装(下)

    登录时用户名和密码错误 默认账号密码 admin/password 管理节点安装好后,初始化数据库,完了使用admin和password登陆提示用户名密码错误,查看日志: Fail to genera ...

  9. JavaScript 常用功能总结

    小编吐血整理加上翻译,太辛苦了~求赞! 本文主要总结了JavaScript 常用功能总结,如一些常用的JS 对象,基本数据结构,功能函数等,还有一些常用的设计模式. 目录: 众所周知,JavaScri ...

  10. C#高级一

    1.单例模式:又叫单件模式,属于创建型模式分类.实际上讲,一个对象只允许创建一个实例,并且提供了一个全局的访问点.  (静态方法生命周期长,消亡时间短,GC不回收) ================= ...