美文网首页
从 函数 到 Swift

从 函数 到 Swift

作者: overla5 | 来源:发表于2019-10-30 23:18 被阅读0次

    函数是一段完成某个事务的代码片段

    定义

    func 函数名(参数列表) -> 返回值类型 {
        // :TODO
        return or not 
    }
    
    * 函数的参数可以省略,但是包裹着参数的 () 不可以省略
    * 返回值为 -> void 的时候,意味着无返回值,-> void 也可以省略
    * 本质来说,函数和方法是同一种东西,只不过方法是定义在函数内部的函数,我们称之为方法
    

    类型

    参数的有无返回值的有无 可以组成4种基本情况

    1.无参无返

    比如:我们想写一个函数 打印字符串 "helloworld"
    
    * Void v是大写
    
    func printAction() -> Void {
        print("helloworld")
    }
    
    上面这段代码无返回值,没有return操作,可以省略 -> Void,等价于
    
    func printAction() {
        print("helloworld")
    }
    
    printAction() 
    /// helloworld
    

    2.无参有返

    // 没有参数,返回值的类型 是 字符串String
    
    func printAction() -> String {
        return "Swift"
    }
    
    var str = printAction()  // 接收返回值
    
    print("\(str) 是最好的语言")
    /// Swift 是最好的语言
    

    3.有参有返

    // 传入 2个 Int 类型的参数,返回值也是 Int 类型
    
    func printAction(num1: Int,num2: Int) -> Int {
        return num1 + num2
    }
    
    printAction(num1: 2, num2: 3)
    /// 5
    

    4.有参无返

    // 传入一个 String 类型的参数,没有返回值
    
    func printAction(s1: String) {
         print(s1) 
    }
    
    printAction(s1: "Swift is ok")
    /// Swift is ok
    

    5.隐式返回

    # 🐷:当函数 执行语句中的表达式 是 单一表达式的时候,我们可以省略return 字段
    
    func printAction(num1: Int,num2: Int) -> Int {
        return num1 + num2
    }
    
    上面函数等价于
    func printAction(num1: Int,num2: Int) -> Int {
        num1 + num2
    }
    
    

    6.多重返回

    现在我们想做这样一件事,定义一个函数,传入一个数组,返回2个值,一个最大,一个最小
    
    func printAction(array: [Int]) -> (min: Int, max: Int) {
        // 取出数组第一个,同时赋值给 当前最小值,最大值
        var curMin = array[0] 
        var curMax = array[0]
        
        // 从第二个开始遍历,也就是下标1
        for item in array[1..<array.count] {
            if item < curMin {
                curMin = item
            } else if item > curMax {
                curMax = item
            }
        }
        return (curMin, curMax)
    }
    
    print(printAction(array: [1,2,3,4,5]))
    /// (min: 1, max: 5)
    

    7.可选返回类型

    如果说上面的案例我们传入的数组是空呢?那么在 访问array[0] 的时候就会发生 运行时错误

    所以我们需要 定义 返回值为可选型,假如传入的数组为空时,我们返回nil

    func printAction(array: [Int]) -> (min: Int, max: Int)? {
        // 这里我们首先判断是否为空,为空返回nil
        if array.isEmpty {
            return nil
        }
        
        var curMin = array[0]
        var curMax = array[0]
        for item in array[1..<array.count] {
            if item < curMin {
                curMin = item
            } else if item > curMax {
                curMax = item
            }
        }
        return (curMin, curMax)
    }
    
    # 既然返回值是可选型,那么我们取值的时候就要注意了
    
    * 返回值类型是 元祖,我们可以定义一个元祖去接收
    * 如果元祖有值,我们可以进if,反之进else
    
    var tuples = printAction(array: [])
    
    if let result = tuples {
        print(result.0,result.1)
    } else {
        print("我是空的")
    }
    

    可选绑定 if let 介绍

    函数的标签以及参数

    每个函数都包含 参数标签参数名称,而 参数标签大大增加了代码的可读性

    func someFuction(参数标签 参数名称: 参数类型) {
        // do something
        ...
        // 参数标签 和  参数名称 以 空格分隔
        // 参数标签可以省略
    }
    

    比如说

    func eatFuction(food: String, who:String) {
        print("今天和\(who) 吃了\(food)")
    }
    
    eatFuction(food: "麻辣烫", who: "表弟")
    
    // 这样的调用 如果不明白函数内部实现的人,其实是懵逼的
    // foot 和 who 有什么联系?
    // 麻辣烫是表弟做的吗?
    
    * 如果加上参数标签呢?
    
    func eatFuction(eat food: String, with who:String) {
        print("今天和\(who) 吃了\(food)")
    }
    
    那么的调用就是这样
    
    eatFuction(eat: "kfc", with: "表弟")
    // 今天和表弟一起吃了kfc
    // 有没有一种豁然开朗的感觉,没错 是我带他吃的
    

    省略参数标签 _

    如果我们想省略一些参数,我们并不想知道 参数代表的含义,可以使用下划线 _来操作

    并不关心这个参数
    比如:

    func eatFuction(_ food: String, _ who:String) {
        print("今天和\(who) 吃了\(food)")
    }
    
    eatFuction("饭", "别人")
    
    // 今天和别人吃了饭,我管你是谁
    

    默认参数

    函数的参数中我们是可以添加默认值的,用来表达一些默认的值,也许不会修改
    比如 去图书馆看书

    # 含有默认值的参数列表,函数默认会提供2个初始化构造方法
    # 一个包含默认值可以改,一个不包含默认值
    
    func defuleFuction(whichPlace: String, todo: String = "读书") {
        print("我每天都去\(whichPlace) \(todo)")
    }
    
    defuleFuction(whichPlace: "图书馆")
    
    // 我每天都是图书馆看书
    // 我只要写地点,不需要写干什么
    
    * 假如我想更改这个默认值,
    
    defuleFuction(whichPlace: "图书馆",todo: "看妹子")
    // 那么我也可以去图书馆 看妹子呀
    

    可变参数

    可变参数 顾名思义就是 参数是可变的,当我们不确定参数值的数量时,可以用 省略号... 来表示这个参数是可变的

    // 我们定义一个函数,累加我们传入的数值
    
    func variableFuction(_ varialbeStrings: Int...,num: Int) -> Int {
        var total = 0
        for item in varialbeStrings {
            total += item
        }
        return total + num
    }
    print(variableFuction(1,2, num: 3))
    
    // 可以看到 我把可变参数写在了第一个参数,这样是不建议的
    
    # 注意
    * 一个函数最多只能拥有一个可变参数
    * 有可变参数的时候 ,最好写在后面,易读
    * 有可变参数的时候,另外的参数不可以省略名称
    
    也就是说我这么写 是错误的 ❌
    func variableFuction(_ varialbeStrings: Int...,_: Int) -> Int {
    // 省略了num 报错
    

    输入输出参数 inout

    这2段代码我们来看一下

    // 传入一个Int 分别加 1,然后返回
    
    ✅
    func addFuction(num: Int) -> Int {
        return num + 1
    }
    
    ❌
    func addOtherFuction(num: Int) -> Int {
        num += 1
        return num
    }
    
    # 🐷
    # 事实上Swift 会默认认为 所有可能的地方 都是 不可变的,毕竟是静态语言
    # 所以 函数的声明中,参数默认都是 let 修饰的
    
    第一种方法里,num +1 ,相当于我们创建了一个临时变量
    var temp = num + 1,我们改变的是temp 的值
    
    而第二种方法,我们是在改变num 自身的值,这是不被允许的
    
    那么我们显示调用var ?
    
    func addOtherFuction(var num: Int) -> Int {
        num += 1
        return num
    }
    # error: 'var' as a parameter attribute is not allowed,也是不可以的
    

    # 所以我们引入了 inout,输入输出函数

    默认情况下,函数的参数传递是值传递,因为Int 是值类型 如果想改变函数外面的变量,则需要传递变量的地址

    也就是 说 inout 的本质 是 引用传递,将变量 的指针 通过& 符号 捕获,并且修改指针指向的内存 里的值

    func addOtherFuction( num: inout Int) -> Int {
        num += 1
        return num
    }
    
    var num1 = 9
    var num2 = addOtherFuction(num: &num1)
    
    print(num1)
    print(num2)
    // num1 num2 都是10
    
    # 必须要用 & 符号,类似c语言的取值符,但实际应该更为复杂
    

    函数类型

    每个函数 都有自己的函数类型,它的函数类型 是由 参数类型返回值类型 共同决定的

    我们可以视这个类型为一个整体

    比如

    func printAction(num1: Int,num2: Int) -> Int {
        return num1 + num2
    }
    
    它的函数类型就是 (Int, Int) -> Int
    

    函数类型作为参数

    这里定义了一个addFuction,传入2个数,相加并返回
    
    func addFuction(a: Int, b: Int) -> Int {
        return a + b
    }
    
    // 函数类型是 (Int, Int) -> Int
    // 我们把 上面的函数作为参数 给到新的 函数
    
    func newAddFuction(_ addName: (Int, Int) -> Int, a: Int, b: Int) {
        print(addName(a,b))
    }
    
    可以看到 addFuction这个参数 就是   (Int, Int) -> Int 类型的
    那么我们调用的时候 ,是不是就可以把 第一个函数  addFuction 传给 newAddFuction
    
    newAddFuction(addFuction, a: 2, b: 3)
    
    # 我们也可以定义一个类型 指向这个类型 
    # 比如 var mathFunction: (Int, Int) -> Int = addFuction
    那么 newAddFuction 也可以写为:
    
    func newAddFuction(_ addName: (Int, Int) -> Int, a: Int, b: Int) {
       print(addName(a,b))
    }
    
    newAddFuction(tempFunction, a: 2, b: 3)
    

    函数类型作返回值

    把参数类型 在函数体内 当做一个整体 返回

    func addFuction(a: Int, b: Int) -> Int {
        return a + b
    }
    
    // 通过getAddFuction  拿到 addFuction
    // 因为返回值类型 和  addFuction 类型一样 都是  (Int, Int) -> Int
    
    func getAddFuction() -> (Int, Int) -> Int {
        return addFuction
    }
    
    let newAction = getAddFuction()
    
    print(newAction(3,4))
    

    后续还会在补充 还请多多指点

    谢谢

    相关文章

      网友评论

          本文标题:从 函数 到 Swift

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