Swift入门: 函数

2020-03-19 20:47:58 浏览数 (1)

函数使您可以定义执行特定功能的可重用代码段。通常,函数能够接收一些值来修改其工作方式,但这不是必需的。

让我们从一个简单的函数开始:

代码语言:javascript复制
func favoriteAlbum() {
    print("My favorite is Fearless")
}

如果您将该代码放到playground上,将不会打印任何内容。是的,这是正确的。没有打印任何内容的原因是,我们已将“My favorite is Fearless”消息放置到名为favouriteAlbum()的函数中,并且直到我们要求Swift运行favouriteAlbum()函数时,该代码才会被调用。为此,请添加以下代码行:

代码语言:javascript复制
favoriteAlbum()

该函数运行(或“调用(call)”)该函数,因此现在您将看到“My favorite is Fearless”打印出来。

如您所见,您可以通过编写func来定义一个函数,然后编写函数名称,然后打开和关闭括号,然后再编写一段用打开和关闭花括号标记的代码。然后,您可以通过写入函数名称以及其后的右括号和右括号来调用该函数。

当然,这是一个无聊的例子——该函数无论做什么都执行相同的操作,因此它没有任何意义。但是,如果我们想每次打印不同的专辑怎么办?在这种情况下,我们可以告诉Swift我们希望函数在调用时接受一个值,然后在其中使用该值。

让我们现在开始:

代码语言:javascript复制
func favoriteAlbum(name: String) {
    print("My favorite is (name)")
}

这告诉Swift我们希望函数接受一个名为“ name”的值(称为“参数(parameter)”),该值应该是字符串。然后,我们使用字符串插值将喜爱的专辑名称直接写入输出消息中。要立即调用该函数,请编写以下代码:

代码语言:javascript复制
favoriteAlbum(name: "Fearless")

鉴于它仍然只是一行代码,您可能仍然想知道关键是什么。好吧,想象一下我们在大型应用程序的20个不同地方使用了该功能,然后您的首席设计师出现并告诉您将消息更改为"I love Fearless so much – it's my favorite!''您是否真的要查找并更改代码中的所有20个实例?可能不会。使用函数,只需更改一次,一切都会更新。

您可以使函数接受任意数量的参数,因此让它接受名称和年份:

代码语言:javascript复制
func printAlbumRelease(name: String, year: Int) {
    print("(name) was released in (year)")
}

printAlbumRelease(name: "Fearless", year: 2008)
printAlbumRelease(name: "Speak Now", year: 2010)
printAlbumRelease(name: "Red", year: 2012)

这些函数参数名称很重要,实际上构成了函数本身的一部分。有时,您会看到多个具有相同名称的功能,例如handle(),但具有不同的参数名称以区分不同的操作。

外部和内部参数名称

有时,您希望在调用函数时以一种方式命名参数,而在函数本身内部以另一种方式命名。这意味着当您调用一个函数时,它几乎使用自然的英语,但是在函数内部,参数具有合理的名称。此技术在Swift中经常使用,因此现在值得去学习和理解。

为了说明这一点,让我们编写一个函数,该函数可以打印字符串中的字母数。使用字符串的count属性可以实现它,因此我们可以这样编写:

代码语言:javascript复制
func countLettersInString(string: String) {
    print("The string (string) has (string.count) letters.")
}

有了该功能,我们可以这样调用它:

代码语言:javascript复制
countLettersInString(string: "Hello")

虽然确实可以,但是有点罗唆。另外,您也不会大声地说:“count letters in string string hello(计算字符串“Hello”字符串的字母数量)”。

Swift的解决方案是让您在调用参数时为其指定一个名称,并在方法内部指定另一个名称。要使用此功能,只需两次写入参数名称——一次用于外部,一次用于内部。

例如,我们可以在调用参数时将其命名为myString,并在方法内部使用str,如下所示:

代码语言:javascript复制
func countLettersInString(myString str: String) {
    print("The string (str) has (str.count) letters.")
}

countLettersInString(myString: "Hello") 

您还可以指定下划线_作为外部参数名称,以告诉Swift它根本不应该具有任何外部名称。例如:

代码语言:javascript复制
func countLettersInString(_ str: String) {
    print("The string (str) has (str.count) letters.")
}

countLettersInString("Hello")

如您所见,这使代码行看起来像一个英语句子:“count letters in string hello(计算“Hello”字符串的字母数量)”。

尽管在很多情况下使用_是正确的选择,但是Swift程序员通常更喜欢命名其所有参数。仔细想想:为什么我们在函数中需要“ String”一词——我们还要在字母上计算什么?

因此,您通常会看到的是外部参数名称,例如“ in”,“ for”和“ with”,以及更有意义的内部名称。因此,编写此函数的“Swifty”方式如下所示:

代码语言:javascript复制
func countLetters(in string: String) {
    print("The string (string) has (string.count) letters.")
}

这意味着您使用参数名称“ in”调用该函数,这在函数内部将毫无意义。但是,在函数内部,相同的参数称为“字符串”,这很有用。因此,该函数可以这样调用:

代码语言:javascript复制
countLetters(in: "Hello")

这才是真正的Swifty代码:“count letters in hello”看起来像自然的英语,但是代码也清晰明了。

PS: 在Swift社区中,短语 "Swifty code" 通常用于描述遵循当前最流行的约定的代码。

返回值

Swift函数可以通过在其参数列表之后写入->然后是数据类型来返回值。完成此操作后,Swift将确保您的函数无论如何都将返回一个值,因此这又是您对代码的作用作出的保证。

例如,让我们编写一个函数,如果专辑是Taylor Swift的专辑之一,则返回true,否则返回false。这需要接受一个参数(要检查的专辑的名称),并将返回一个布尔值。这是代码:

代码语言:javascript复制
func albumIsTaylor(name: String) -> Bool {
    if name == "Taylor Swift" { return true }
    if name == "Fearless" { return true }
    if name == "Speak Now" { return true }
    if name == "Red" { return true }
    if name == "1989" { return true }

    return false
}

如果您想尝试新的switch/case知识,那么这个函数将是一个不错的选择。

现在,您可以通过传递专辑名称并根据结果执行操作来调用它:

代码语言:javascript复制
if albumIsTaylor(name: "Red") {
    print("That's one of hers!")
} else {
    print("Who made that?!")
}

if albumIsTaylor(name: "Blue") {
    print("That's one of hers!")
} else {
    print("Who made that?!")
}

本文来自Hacking with Swift给swift初学者的入门课程Swift for Complete Beginners 的Functions

0 人点赞