美文网首页
Swift5-外行零基础入门_11-函数(中)

Swift5-外行零基础入门_11-函数(中)

作者: DavidShawn | 来源:发表于2020-12-24 08:38 被阅读0次

    函数

    多参数

    我们设计一个能求矩形面积的函数,输入长和宽,就得出面积:

    func rectangle(length: Double, width: Double) -> Double {
        return length * width
    }
    print(rectangle(length: 15, width: 20.8) ) // 312.0
    

    这里,我们设计了lengthwidth两个参数,分别代表了长方形的,并且为他们指定了Double的数据类型。输出的结果也指定为Double类型。包裹代码中,让lengthwidth相乘,得到的就是矩形的面积,用return这个关键字,将结果返出函数。
    在函数外面,任意给这两个参数指定某个长度值,就得到了相应的面积。
    参数还可以更灵活。
    我们继续扩展这个函数。现在,我想让函数能计算面积的同时还能计算周长,可以这样设计:

    func rectangle(length: Double, width: Double, isPerimeter:Bool ) -> Double {
        if isPerimeter {
            return (length + width) * 2
        } else {
            return length * width
        }
    }
    let area = rectangle(length: 10, width: 26, isPerimeter: false)
    let perimeter = rectangle(length: 10, width: 26, isPerimeter: true)
    print("长方形的面积是\(area),周长是\(perimeter)")
    

    注意看,参数还能使用布尔值,包裹代码中就可以做一个判断,如果isPerimetertrue,我们就计算周长,否则,还是计算面积。这样,我在下面引用函数的时候,如果想计算面积,我就将isPerimeter设置为false,想计算周长,就将这个参数设置为true
    怎么样,短短的几行代码,仅仅是参数不同,就可以实现不同的功能。在实际应用时,将大幅节省你的代码量,出错时,也容易排查到是哪里出了问题。

    默认参数

    上面这个例子中,我们想求矩形的面积,仍然要指定isPerimeter: false,这样显得有点啰嗦,能不能直接默认就是求面积呢?
    我们可以使用默认参数:

    func rectangle(length: Double, width: Double, isPerimeter: Bool = false ) -> Double {
        if isPerimeter {
            return (length + width) * 2
        } else {
            return length * width
        }
    }
    let area = rectangle(length: 10, width: 26)
    let perimeter = rectangle(length: 10, width: 26, isPerimeter: true)
    

    在参数中,我们指定isPerimeter的默认值是false,这样,后面我们调用函数时,可以不用指定这个参数的值了,函数会调用默认值。
    而当我们想修改默认值时,只需要再次指定,这样,默认值会被覆盖,使用我们调用函数时指定的新值。

    返回可选型

    上面这个例子中,我们还可以这样改造。当指定isPerimeter为true时,计算周长,而当isPerimeter为false时,什么都不做,返回空值。

    func rectangle(length: Double, width: Double, isPerimeter: Bool ) -> Double? {
        if isPerimeter {
            return (length + width) * 2
        } else {
            return nil
        }
    }
    let area = rectangle(length: 10, width: 26, isPerimeter: false)
    

    注意看,我们返回值加了个?,如果不加,系统会报错。因为我们返回的值可能是Double型,也可能是nil型,这样的不确定性,不就是我们之前说过的可选型吗?所以,我们指定函数的返回值是一个Double可选型,这样,系统就不会报错了。

    多返回值

    如果,我想一次性得到周长和面积,又该怎么办呢?好办!

    func rectangle(length: Double, width: Double ) -> (area: Double, perimeter: Double) {
        let area = length * width
        let perimeter = (length + width) * 2
        return (area, perimeter)
    }
    let newRectangle = rectangle(length: 15, width: 20.2)
    print("长方形的面积是\(newRectangle.area),周长是\(newRectangle.perimeter)")
    

    想要从函数中返回多个值,需要借助元组。
    首先,在返回类型中,我们要分别指定返回的值及其类型。使用return时,将值用元组的形式放在返回值中。最后,调用的时候,用类似调用属性的方式.area.perimeter调用相应的值。

    参数的标签

    参数已经有名称了,比如上面的lengthwidth。Swift仍然具有给参数名再加标签的功能,我们用开始最简单的函数举例。

    func rectangle(chang length: Double, kuan width: Double) -> Double {
        return length * width
    }
    print(rectangle(chang: 15, kuan: 20.8) ) // 312.0
    

    看到没有,我们在length前面加了个changwidth前面加了个kuan,这样,我们在调用的时候,直接使用changkuan就行了。
    我们还可以忽略标签:

    func rectangle(_ length: Double, _ width: Double) -> Double {
        return length * width
    }
    print(rectangle(15,20.8) ) // 312.0
    

    使用_,意思是可以忽略标签,因为参数名本身就是默认标签。这样,我们在调用函数的时候,就不用指定标签,直接按顺序赋值即可。

    可变参数

    在前几个案例中,我们定义好参数,在调用函数的时候,要对参数一一对应的赋值。
    然而,有些情况,我们并不能提前确定好参数的具体数量。
    比如,我想实一个计算商品总价的程序,把我买的商品价格都输入进去,然后算总价。实际上也就是任意n个数的求和。我们可以做样做:

    func totalValue(_ items: Double...) -> Double {
        var sumPrice: Double = 0
        for i in items {
            sumPrice += i
        }
        return sumPrice
    }
    let totalYesterday = totalValue(20.5,58.3,88.2)
    let totalToday = totalValue(322.5,909.2,69.9,12.6)
    

    分析这段代码,首先在参数数据类型的后面加...,然后在包裹的代码块中,遍历参数,然后累加。
    最后,在调用函数的时候,我们实际上可以输入满足数据类型的任意数量的参数。

    输入输出参数

    到目前位置,我们给出的参数,在函数中,都是老老实实的直接使用。如果我在函数中改变参数行不行呢?答案是不行,比如参数给了a = 3,我们不能在函数中这样改变a +=1,这样系统是会报错的,因为默认情况下,参数是常量。
    但是,Swift仍然给了我们一个渠道,可以修改参数的值,这就是输入输出参数。看下面这个例子,我们输入一个人的身高,但是考虑到有鞋的高度,因此我做了一个函数,能够将身高减去一个高度,再返回出来。

    func person(stature: inout Double) -> Double{
        stature = stature - 0.03
        return stature
    }
    var Tom = 1.78
    person(stature: &Tom)
    print(Tom)
    

    首先,我们在参数中加了一个关键字inout,表示这个参数是一个输入输出参数。(注意,可变参数不能加inout,你可以试一下。)
    接着,我们在代码块中对参数值进行了-0.03的操作。
    在调用的时候,我先定义了一个变量:Tom的测量身高是1.78。然后调用了一下函数,这个函数对stature参数进行了修改处理。
    在引用的时候,我们使用了&符号,这个类似与C语言中的指针,就是我们改的变量Tom所指向的内存地址。产生实际上的效果是,函数对外部的变量值进行了修改,因此,我们再次调用Tom的时候,就是修改过的值。
    如果你尝试像这样直接调用函数,print(person(stature: 1.78)),系统会提示,说字面量不可修改,因为你已经用1.78把参数stature写死了,需要把1.78这个位置换成可修改的变量,才能完成参数的加工修改。

    小结与预告

    好了,本节内容先告一段落。
    我们介绍了函数的参数和返回值的一些衍生概念。
    下节,我们将拓展数据类型的概念。

    相关文章

      网友评论

          本文标题:Swift5-外行零基础入门_11-函数(中)

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