学习Swift和iOS开发第4部分:函数

函数是编程中的核心组件。 它们是构建功能应​​用程序的基础。 函数有助于使我们的代码更易读,更分隔并最终更高效。 我们可以编写一个函数来执行特定任务,然后在整个应用程序中随意重用它。

每天,大多数人都按照一套常规生活。 他们经常做的事情甚至没有考虑或意识到自己正在做。

想一想第一次醒来时的工作。 我自己知道,我滑下床,跌跌撞撞地走过房间,走到我嘈杂的电话旁,使闹钟静音。 仅此事件便包含了我每天以相同顺序执行的几个不同步骤(除非我忘记设置闹钟)。

1.唤醒警报声
2.滑下床,尽量不要意外唤醒我的妻子。
3.错开警报。
4.使我的闹钟静音。

上面的步骤是一个功能。 我一遍又一遍地(每天早晨)完成的一组步骤。 在伪代码中,这可能类似于:

  var awake = false 
var inBed = true
var walk = false
var alarmSilenced =否
func getUp(){
醒着=真
inBed =假
行走=真
AlarmSilenced =真
}

函数以自上而下的方式在内部运行代码。

换句话说, awake设置为trueinBed设置为falsewalking设置为truealarmSilenced设置为true

但是,我的唤醒隐喻并不完美,因为我大概需要10到15秒钟才能完全醒来,走过去并使警报静音。 现代设备可以如此快速地处理函数内部的代码,即使它逐行地运行在每一行代码中,它几乎就像是立即在运行。

简单地说,函数是一种使用给定的集合或参数执行特定动作的方法。 您将在本系列稍后将完成的许多高级项目中使用它们。

但是关于功能的讨论已经足够了……让我们来写一些吧!

创建您的第一个功能

如果您上过任何高级数学课程,则可能具有一些有关函数的背景知识。 您可能以其他名称知道它们:公式。 您可以使用L x W (长度乘以宽度)来计算矩形的面积,或者使用a ^ 2 + b ^ 2 = c ^ 2来确定直角三角形的斜边的长度。

我们将在Swift中创建这些公式之一,以说明函数的工作方式。 🙂

首先,如果尚未打开Xcode,请点击Create New Playground 。 给它起一个类似于Function的名称,然后单击Next
选择某个位置保存此.playground文件,然后单击
Create以保存它。 您应该会看到类似下面的屏幕。

删除左侧的所有样板代码,但根据需要保留import UIKit

要声明一个函数,我们需要:
1.以关键字开头
func
2.给它一个描述性的名称,类似于我们给变量命名的方式。
3.在我们想要传递的任何参数中包括一组括号和括号。
4.声明函数应返回的值(如果有)。

在您的游乐场中,键入以下内容:

  func computeArea(length:Int,width:Int)-> Int { 
//计算面积的代码将在此处。
}

由于目前存在,我们已经声明了一个称为calculateArea(length:width:)的函数。 function内没有代码,我们传入的长度和宽度值都是Int类型。 我们还声明了要通过键入-> Int返回Int的值。 让我们添加一些代码来计算面积。

  func computeArea(length:Int,width:Int)-> Int { 
令面积=长*宽
返回区
}

现在我们的功能已经完成。 我们创建了一个函数来计算矩形的面积。 我们可以传入长度和宽度的值(两者都是必需的),函数中的代码将它们相乘以得到一个面积值。
然后我们
return area的值。 但是在Playground中,我们的功能不会像应有的那样打印到控制台。

那是因为我们还没有打电话。 我们需要键入函数的名称并传递长度和宽度的值,以便Xcode知道在内部运行代码。

在“操场”窗口的底部,通过键入函数名称来调用该函数。 使用Xcode的自动完成功能,然后在弹出时按Enter键,使您的生活更轻松。 输入长度10和宽度20。

  func computeArea(length:Int,width:Int)-> Int { 
令面积=长*宽
返回区
}
computeArea(长度:10,宽度:20)

要查看函数的结果,请查看Playground窗口的右侧(如下),以查看函数从area变量返回的值。

让我们尝试再次调用它,但是传入不同的值以计算不同的面积。

  func computeArea(length:Int,width:Int)-> Int { 
令面积=长*宽
返回区
}
computeArea(长度:10,宽度:20)
computeArea(长度:24,宽度:15)

如您所见,该函数可用于边长为整数的任何区域的矩形。

另一个功能示例

函数可以用于任何东西! 上面我们使用它们进行了简单的面积计算,现在我们将写一个有关我们的银行帐户的信息。

在您的Playground文件的底部,键入以下内容:

  var bankAccountBalance = 500.00 
var selfLacingNikes = 350.00

我们创建了两个变量-一个用于管理银行帐户余额,另一个用于声明一些凉爽的自动鞋带的价格。 伟大的斯科特!

我们可以只写出条件代码,说如果我们有足够的钱,那么我们可以买鞋,但是功能是做到这一点的更好方法。 这样,我们可以重用该功能并将其应用于其他商品价格。

  var bankAccountBalance = 500.00 
var selfLacingNikes = 350.00
func PurchaseItem(currentBalance:Double,itemPrice:Double)-> Double {
如果itemPrice <= currentBalance {
print(“ $ \(itemPrice)的采购项目”)
返回currentBalance — itemPrice
}其他{
print(“您破产了。余额仍然在$ \(currentBalance)”)
返回currentBalance
}
}

刚刚发生了什么?

好吧,哇 to这是很多代码,没有任何解释。 现在让我们谈谈。

我们声明一个名为purchaseItem(currentBalance:itemPrice:)的函数。
我们给它两个参数来接受输入值-
currentBalanceitemPrice
接下来,我们要求函数返回类型的值
完成运行后Double

在函数内部,我们写道,如果传入的itemPrice小于或等于传入的currentBalance值,则我们应该1.)打印Purchased item for $\(itemPrice)并2.)返回currentBalance减去项目的价钱。

如果不能满足该条件,或者在我们的代码中不能满足: else ,我们的功能将1.)打印: You are broke. Balance still at $\(currentBalance) You are broke. Balance still at $\(currentBalance)和2.)返回当前余额的值不变。

在我们操场的底部,让我们现在调用我们的函数。

  var bankAccountBalance = 500.00 
var selfLacingNikes = 350.00
func PurchaseItem(currentBalance:Double,itemPrice:Double)-> Double {
如果itemPrice <= currentBalance {
print(“ $ \(itemPrice)的采购项目”)
返回currentBalance — itemPrice
}其他{
print(“您破产了。余额仍然在$ \(currentBalance)”)
返回currentBalance
}
}
//在下面传递“ bankAccountBalance”和“ selfLacingNikes”的值。purchaseItem(currentBalance:bankAccountBalance,itemPrice:selfLacingNikes)

如您在右侧所见,该功能有效! 我们的商品价格低于我们的帐户余额,因此发生操作500.00–350.00以便将鞋子的价格减去我们的帐户余额。 这使我们的bankAccountBalance值为150.00。

要实际使用该值进行操作,我们可以将返回值设置为等于bankAccountBalance以在函数运行后对其进行更新。

  …bankAccountBalance = PurchaseItem(currentBalance:bankAccountBalance,itemPrice:selfLacingNikes) 

现在bankAccountBalance等于150.00而不是500.00,因为我们的函数已对其进行了修改,并在Debug菜单中打印了一条消息(如下所示)。

我们也可以创建一个新商品来购买并通过我们的功能将其传递!

selfLacingNikes下创建一个名为stainlessSteelAppleWatch的变量,并将其价格设置为599.00,如下所示:

  var bankAccountBalance = 500.00 
var selfLacingNikes = 350.00
var StainlessSteelAppleWatch = 599.00

现在将其传递给我们的purchaseItem(currentBalance:itemPrice:)函数:


bankAccountBalance = PurchaseItem(currentBalance:bankAccountBalance,itemPrice:不锈钢AppleWatch)

如下所示,我们的功能可防止进行购买并为我们打印错误消息。

字符串插值

itemPrice ,让我们讨论为什么我使用\()并将itemPrice放在其中,即\(itemPrice)

在Swift中,当您要打印消息或创建String值并包括其他类型的值时,我们可以将其传递并使用String Interpolation进行转换。 像这样:

  var价格= 250 
var message =“该商品的价格为$ \(价格)。”

将显示在控制台上的消息是:“该商品的价格为250美元。”

可变price类型为Int (由Swift推断),并使用语法\()传入和内插。 太酷了!

返回值是道路的尽头

每当您在函数中调用return时,函数即结束。 返回后编写的代码将永远无法运行。 因此,请确保所有编写的代码都在return语句之前。

这是一个不好的例子:

  var pizzaSlices = 8 
var amountOfPizzaEaten = 2
func eatPizza(slicesEaten:Int,pizzaSlices:Int)-> Int {
如果slicesEaten> = 1 {
让updateSlices = pizzaSlices — slicesEaten
返回updateSlices
print(“ \(updatedSlices)剩下的披萨片!”)
}其他{
打印(“嗯,不饿。”)
返回披萨
}
}
eatPizza(slicesEaten:amountOfPizzaEaten,pizzaSlices:pizzaSlices)

你能找到错误吗?

return之后调用的打印函数将永远不会运行,因为一旦按下return键,该函数将停止执行。 实际上,Xcode甚至会警告我们以后编写的代码将无法运行。 我们的函数应该看起来像这样:

  var pizzaSlices = 8 
var amountOfPizzaEaten = 2
func eatPizza(slicesEaten:Int,pizzaSlices:Int)-> Int {
如果slicesEaten> = 1 {
让updateSlices = pizzaSlices — slicesEaten
print(“ \(updatedSlices)剩下的披萨片!”)
返回updateSlices
}其他{
打印(“嗯,不饿。”)
返回披萨
}
}
eatPizza(slicesEaten:amountOfPizzaEaten,pizzaSlices:pizzaSlices)

选择不退货

如果我们不想处理返回值怎么办? 好吧,感谢inout参数,我们不必这样做。
一个
inout参数允许我们直接在函数外修改变量,而不必返回值以更新它们的值。

您可以通过修改上面编写的Pizza函数来使用inout参数,注意在参数名称后的inout以及在调用时传递给函数的参数前面的&

  var pizzaSlices = 8 
var amountOfPizzaEaten = 2
func eatPizza(slicesEaten:Int,pizzaSlices:inout Int){
如果slicesEaten> = 1 {
pizzaSlices = PizzaSlices-slicesEaten
打印(“ \(pizzaSlices)剩下的披萨片!”)
}其他{
打印(“嗯,不饿。”)
}
}
eatPizza(slicesEaten:amountOfPizzaEaten,pizzaSlices:&pizzaSlices)

在我们函数的if块中,我们可以直接修改超酷的变量pizzaSlices
当我们调用函数
eatPizza(slicesEaten:pizzaSlices:)我们在pizzaSlices变量的前面添加一个&符号。这是告诉Xcode我们要使用inout参数的语法。

通过以这种方式编写函数,不需要返回值,但是我们仍然可以修改所需的变量。 您想少量使用它,并且您不需要了解这一点,但是最好将它放在工具带中。

常数

在整个本文中,您已经看到let以与创建变量类似的方式使用了关键字。 该关键字实际上非常重要。 它用于在Swift中声明一个Constant

常量与变量完全一样,除了一个常量一旦赋予值就永远不会改变。

可能是常量的数据示例包括:您的生日,城市名称,汽车型号等。永远不变且保持不变的事物(因此得起名字!)。 关键字let以“让值保持不变”的方式使用。

以下是一些伪代码示例:

 生年= 1992 
让mothersMaidenName =“ Squillagree”
让jennysPhoneNumber = 8675309

这些值都是不变的,我们不需要更改它们。 如果我们尝试更改它们,Xcode会大吼大叫,将我们创建的let显示为灰色的var ,并给我们一个错误,要求我们将let更改为var以便可以对其进行修改,如下所示:

如果可以,则应始终使变量恒定。 实际上,Xcode编译器会发出警告,如果它检测到代码中的任何地方都未对var进行突变(更改),则可以将var更改为let 。 如果Xcode知道一个变量永远不会改变,则可以对其进行优化,从而加快代码执行速度。

包起来

在这篇文章中,我们已经学到了很多有关功能的知识-执行特定任务的可重用代码段。 编码的很大一部分是编写和使用函数,因此这对于您熟悉和理解非常重要。

我们讨论了包含关键字func ,该函数的功能的描述性名称,一组括号(可选地包括要传入的参数)和返回类型(如果需要)的函数的结构。

在下面的帖子中,您将经常使用函数,因此,如果您对该帖子的任何部分不甚了解,请再次阅读并确保您真正了解它。 在下一篇文章中,我们将学习Swift集合。


行使
编写一个名为
canDivideSlices具有两个值canDivideSlicesnumberOfFriends并返回Bool类型的值(true或false)。 此功能将用于确定比萨饼是否可以由您的朋友组平均分配。