美文网首页
swift基础——函数

swift基础——函数

作者: 夜凉听风雨 | 来源:发表于2022-03-09 20:08 被阅读0次

函数分类

  • 无参无返

下面三种方式都可以
Void在swift里的定义就是空元组()

func say() -> Void {
    print("hello")
}

func say() -> () {
    print("hello")
}

func say() {
    print("hello")
}

  • 无参有返
func pi() -> Double {
    return 3.14
}
  • 有参无返
func say(text:String) {
    print(text)
}
  • 有参有返

函数的形参是let,也只能是let

func add(a:Int, b:Int) -> Int {
    return a + b
}

隐式返回

如果整个函数体是一个单一表达式,那么函数会隐式返回这个表达式

func add(a:Int, b:Int) -> Int {
    a + b // 可以省略return
}

let sum = add(a: 10, b: 20)
print(sum) // 打印: 30

函数的文档注释

注释及其效果.png

参数标签

可以修改参数标签,这样的目的是为了让函数调用的时候,更像是一个完整的英文句子,更好理解函数的意思。

func goToWork(at time:String) {
    print("time is \(time)")
}

goToWork(at: "8:00") // 很像 go to work at 8:00

可以使用下划线_省略参数标签,不过不建议这么使用

func add(_ a:Int, _ b:Int) -> Int {
    return a+b
}
add(10, 20) 

默认参数值

可以在声明方法的时候,为参数设置一个默认值,当方法调用时没传入该参数时,该参数值为默认值。

func check(name: String = "Jonas", age: Int, job: String = "none") {
    print("name=\(name),age=\(age),job=\(job)")
}

check(age: 15) // name=Jonas,age=15,job=none
check(name: "Bob", age: 20, job: "Doctor") // name=Bob,age=20,job=Doctor
check(name: "Mary", age: 18) // name=Mary,age=18,job=none
check(age: 30, job: "postman") // name=Jonas,age=30,job=postman

可变参数

在参数类型后面加...表示可以传入不等数量的参数,相当于是一个数组

  • 一个函数最多只能有一个可变参数
func countNumber(numbers: Int...) {
    print(numbers) // [1,2,3,4,5]
}
countNumber(numbers: 1,2,3,4,5)
  • 紧跟在可变参数后面的参数不能省略参数标签

下面的例子在可变参数numbers后面的是student参数,它不能使用下划线来省略参数标签。

func countNumber(numbers: Int..., student: String, _ age: Int) {
    print(numbers) // [1,2,3,4,5]
}

countNumber(numbers: 1,2,3,4,5, student: "Bob", 15)

输入输出参数(In-Out-Parameter)

  • 可以用inout定义一个输入输出参数:可以在函数内部修改外部实参的值
  • 输入输出参数在传参时要加 &
  • 可变参数不能标记为输入输出参数
  • inout参数不能有默认值
  • inout参数的本质是地址传递(引用传递)
  • inout参数只能传入可以被多次赋值的
    let修饰的常量就不可以,或者直接传一个字面量也不可以。
func change(num: inout Int) {
    num = 20
}

var number = 10
change(num: &number)
print(number) // 20

函数重载

重载的函数可以和原函数共存,虽然有多个名字一样的函数,但是也可以根据情况不同调用不同的函数。

  • 规则
    1、函数名相同
    2、参数个数不同 || 参数类型不同 || 参数标签不同
函数重载示例.png 调用重载函数.png
  • 返回值类型不构成重载
    下图所示两个方法只有返回值类型不同,但是不构成重载,调用会报错。
返回值重构问题.png
  • 默认参数值和函数重载一起使用产生二义性时,编译器并不会报错(在C++中会报错)
默认参数值重构问题.png
  • 可变参数、省略参数标签、函数重载一起使用产生义性时编译器有可能会报错
可变参数省略参数标签重载.png

内联函数

  • 如果开启了编译器优化( Release模式默认会开启优化) , 编译器会自动将某些函数变成内联函数
    将函数调用展开成函数体
编译器优化配置.png
  • 哪些函数不会被内联?
    1、函数体比较长:函数体太长如果内联,多次调用会增大汇编代码数量
    2、包含递归调用:会导致死循环
    3、包含动态派发:在编译时无法确定调用方法

@inline

// 永远不会内联,即使开启了编译器优化
@inline(never) func test() {
    print("hello")
}

// 开启编译器优化后,即使函数内的代码很多,也会被内联(递归调用函数,动态派发的函数除外)
@inline(__always) func test() {
    // ...很多的代码
}

release模式下,编译器开启优化,会自动决定内联函数,所以这个@inline也基本不用。

函数类型

  • 每一个函数都是有类型的,函数类型由形式参数类型、返回值类型组成
func method() {} // 函数类型:() -> Void 或者() -> ()

func add(a: Int, b: Int) -> Int {
    return a + b
} // 函数类型:(Int, Int) -> Int
  • 使用函数类型,可以定义变量
func method() {} // 函数类型:() -> Void 或者() -> ()

func add(a: Int, b: Int) -> Int {
    return a + b
} // 函数类型:(Int, Int) -> Int

var fn : (Int, Int) -> Int = add
fn(10, 20) // 30 调用时不需要参数标签
  • 使用函数类型,可以作为参数类型
func add(a: Int, b: Int) -> Int {
    return a + b
} // 函数类型:(Int, Int) -> Int

func printResult(mathFn: (Int, Int) -> Int, a: Int, b: Int) {
    let result = mathFn(a, b)
    print(result)
}

printResult(mathFn: add, a: 20, b: 30) // 50
  • 函数类型作为函数返回值
    返回值是函数类型的函数,叫做高阶函数
func add(num: Int) -> Int {
    return num + 1
}

func reduce(num: Int) -> Int {
    return num - 1
}

func select(result: Bool) -> (Int) -> Int {
    return result ? add : reduce
}

// select返回的是add函数
select(result: true)(10) // add函数传入10结果为11

typealias

typealias用来给类型起别名

// 为一个元组起别名为DateType
typealias DateType = (year: Int, month: Int, day: Int)

func method(date: DateType) {
    print("今天是\(date.year)年\(date.month)月\(date.day)日")
}
method(date: (2022, 3, 10)) // 今天是2022年3月10日
// 为一个函数类型起别名为fnType
typealias fnType = (Int, Int) -> Int

func add(a: Int, b: Int) -> Int {
    a + b
}

let method : fnType = add
method(10, 20) // 30

嵌套函数

  • 将函数定义在函数内部
    嵌套函数可以将内部的函数隐藏起来,不让外部直接调用
func selectMethod(result: Bool) -> (Int, Int) -> Int {
    func add(a: Int, b: Int) -> Int {
        a + b
    }
    
    func reduce(a: Int, b: Int) -> Int {
        a - b
    }
    
    return result ? add : reduce
}

let fn = selectMethod(result: true) // add
fn(10, 20) // 30

相关文章

  • Swift 语言基础

    Swift 语言基础 Swift语言介绍 Swift基础部分 第一个Swift程序 Swift没有main函数,第...

  • Swift5 基础教程与进阶合集

    Swift5 基础 Swift5 基础(一)Swift编译流程、基础语法、流程控制、函数、枚举[https://w...

  • Swift5.0 - day1-基础介绍与基本运算

    一、基础知识 1.1、Swift 不用编写main函数(本质上swift是有main函数的),Swift将全局范围...

  • Swift 基本语法(函数, 闭包)

    前言 接上篇, 这篇聊一下 Swift中的 函数, 闭包 一 函数 二 闭包 Swift 基础 先介绍三篇, ...

  • Swift基础 - 函数

    函数的格式func 函数(参数名:参数类型,.....) -> 返回值 { 代码实现} 函数返回值为空的三...

  • Swift基础--函数

    Swift基础--函数 函数式用来完成特定任务的独立的代码块.我们给一个函数起一个合适的名字,用来表示函数做什么,...

  • swift基础_函数

    一.闭包简介 一个函数和它所捕获的变量/常量环境组合起来,成为闭包 如果闭包捕获了局部变量,那么会将该局部变量保存...

  • swift基础——函数

    函数分类 无参无返 下面三种方式都可以Void在swift里的定义就是空元组() 无参有返 有参无返 有参有返 函...

  • RxSwift 核心逻辑初探

    RxSwift RxSwift: Reactive Extensions Swift,函数响应式编程的基础框架。简...

  • Swift5复习(一)Swift编译流程、基础语法、流程控制、函

    Swift5复习(一)Swift编译流程、基础语法、流程控制、函数、枚举Swift5复习(二)可选项、结构体、类、...

网友评论

      本文标题:swift基础——函数

      本文链接:https://www.haomeiwen.com/subject/xbatdrtx.html