学习Swift和iOS开发第4部分:函数
函数是编程中的核心组件。 它们是构建功能应用程序的基础。 函数有助于使我们的代码更易读,更分隔并最终更高效。 我们可以编写一个函数来执行特定任务,然后在整个应用程序中随意重用它。
每天,大多数人都按照一套常规生活。 他们经常做的事情甚至没有考虑或意识到自己正在做。
想一想第一次醒来时的工作。 我自己知道,我滑下床,跌跌撞撞地走过房间,走到我嘈杂的电话旁,使闹钟静音。 仅此事件便包含了我每天以相同顺序执行的几个不同步骤(除非我忘记设置闹钟)。
1.唤醒警报声
2.滑下床,尽量不要意外唤醒我的妻子。
3.错开警报。
4.使我的闹钟静音。
上面的步骤是一个功能。 我一遍又一遍地(每天早晨)完成的一组步骤。 在伪代码中,这可能类似于:
var awake = false
var inBed = true
var walk = false
var alarmSilenced =否
func getUp(){
醒着=真
inBed =假
行走=真
AlarmSilenced =真
}
函数以自上而下的方式在内部运行代码。
换句话说, awake
设置为true
, inBed
设置为false
, walking
设置为true
, alarmSilenced
设置为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:)
的函数。
我们给它两个参数来接受输入值-
currentBalance
和itemPrice
。
接下来,我们要求函数返回类型的值
完成运行后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
具有两个值canDivideSlices
和numberOfFriends
并返回Bool
类型的值(true或false)。 此功能将用于确定比萨饼是否可以由您的朋友组平均分配。