# Swift 函数参数和返回值

> 原文： [https://www.programiz.com/swift-programming/function-parameter-return-values](https://www.programiz.com/swift-programming/function-parameter-return-values)

#### 在本文中，您将学习不同的用户定义函数，这些函数将通过示例获取不同类型的输入并返回输出。

在上一篇文章 [Swift Functions](/swift-programming/functions "Swift Functions") 中，我们了解了函数。 现在，我们将探讨在 Swift 中创建函数的不同方式和类型，即在函数中处理输入和输出。

## 没有参数且没有返回值的函数

这些类型的函数不接受任何输入和返回值。

```swift
func funcname() {
    //statements
}
OR
func funcname() -> () {
    //statements
}
OR
func funcname() -> Void {
    //statements
}
```

以上所有语法对于创建不带参数且不返回值的函数都是有效的。

上面的语法`func funcname() -> ()`也等同于`func funcname() -> Void`，因为`Void`只是`()`的类型别名。 您可以访问 [Swift Typealias](/swift-programming/typealias "Swift typealias") 了解更多信息。

### 示例 1：没有传递参数，也没有返回值

```swift
func greetUser() {
    print("Good Morning!")
}
greetUser() 
```

当您运行上述程序时，输出将是：

```swift
Good Morning!
```

* * *

## 没有参数但返回值的函数

这些类型的函数不接受任何输入参数，而是返回一个值。 要添加返回类型，您需要添加箭头（`->`）和返回类型。

```swift
func funcname() -> ReturnType {
    //statements
    return value
}
```

### 示例 2：没有传递参数但返回值

```swift
func greetUser() -> String {
    return "Good Morning!"
}
let msg = greetUser()
print(msg) 
```

运行该程序时，输出为：

```swift
Good Morning!
```

在上面的程序中，您将返回类型定义为`String`。 现在，该语句必须从函数内部的语句中返回一个字符串，否则您将收到错误。

`return`关键字将程序的控制权从函数主体转移到函数调用。 如果需要从函数返回值，请在`return`关键字后添加值。

`return "Good Morning!"`语句从该函数返回`String`类型的值。 请注意，返回类型和值必须匹配。

您还可以将返回值分配给变量或常量。`let msg =`将返回值分配给常数`msg`。 因此，语句`print(msg)`输出`"Good Morning!"`。

如果您想忽略该值，则可以简单地将`_`用作`let _ =`。

* * *

## 具有参数但没有返回值的函数

参数用于在函数中输入。 该参数包含一个参数名称和类型，后跟一个冒号（`:`）。 这些类型的函数采用输入参数，但不返回值。

```swift
func funcname(parameterName:Type) {
    //statements
}
```

### 示例 3：传递参数但没有返回值

```swift
func greetUser(msg:String) {
    print(msg)
}
greetUser(msg: "Good Morning!") 
```

运行该程序时，输出为：

```swift
Good Morning!
```

在上述程序中，该函数接受类型为`String`的单个参数。 该参数只能在函数内部使用。`msg`是参数的名称。

您可以通过向函数传递参数名称为`greetUser(msg: "Good Morning!")`的字符串值来调用该函数。`msg`参数名称仅在函数`greetUser()`内部可见。

因此，语句`print(msg)`输出`"Good Morning!"`。

* * *

## 具有参数和返回值的函数

这些类型的函数使用参数，还返回值。

```swift
func funcname(parameterName:Type) -> ReturnType {
    //statements
}
```

### 示例 4：传递参数并返回值

```swift
func greetUser(name:String) -> String {
    return "Good Morning! " + name
}
let msg = greetUser(name: "Jack")
print(msg) 
```

运行该程序时，输出为：

```swift
Good Morning! Jack
```

在上述程序中，该函数接受`String`类型的单个参数，并且还返回字符串值`Good Morning! Jack`。

* * *

## 具有多个参数和多个返回值的函数

这些类型的函数采用以逗号分隔的多个参数，并且还返回多个值。 您可以使用元组在 Swift 中返回多个值。 有关更多信息，请参见 *Swift 元组*。

```swift
func funcname(parameterName:Type, parameterName2:Type ,...) -> (ReturnType, ReturnType...) {
    //statements
}
```

### 示例 5：传递了多个参数和多个返回值

```swift
func greetUser(name:String, age:Int) -> (String, Int) {

    let msg = "Good Morning!" + name
    var userage = age
    if age < 0 {
            userage = 0
    }
    return (msg, userage)
}
let msg = greetUser(name: "Jack", age: -2)
print(msg.0)
print("You have \(msg.1) coins left") 
```

运行该程序时，输出为：

```swift
Good Morning!Jack
You have 0 coins left 
```

在上述程序中，函数`greetUser()`接受类型为`String`和`Int`的多个参数。 该函数还以`String`和`Int`类型的元组返回多个值。

要访问每个返回值，我们使用索引位置 0，1… 在这里，我们使用`msg.0`访问`Good Morning!Jack`和`msg.1`访问 **0**。

有时使用索引位置可能不直观且不可读。 我们可以通过给名称指定返回值来优雅地解决此问题。 上面的程序也可以如下重写。

### 示例 6：具有名称的多个返回值

```swift
func greetUser(name:String, coins:Int) -> (name:String, coins:Int) {

    let msg = "Good Morning!" + name
    var userCoins = coins
    if coins < 0 {
        userCoins = 0
    }
    return (msg, userCoins)
}

let msg = greetUser(name: "Jack",coins: -2)
print(msg.name)
print("You have \(msg.coins) coins left") 
```

在此程序中，返回类型为元组，其中包含具有该类型的变量名称。 这样的主要优点是您可以使用变量名称`msg.name`和`msg.coins`而不是访问结果`msg.0`和`msg.1`。

* * *

## 具有参数标签的函数

定义接受输入的函数时，可以在参数名称的帮助下定义输入名称。 但是，还有另一种名称可以与参数名称一起使用，称为参数标签。

参数标签的使用允许以表达方式，类似于句子的方式调用函数，同时仍提供可读且意图明确的函数主体。

每个函数参数都具有参数标签和参数名称。 默认情况下，参数使用其参数名称作为其参数标签。 但是，如果您显式定义参数名称，则在调用函数时会使用参数标签。

带参数标签的函数的语法为

```swift
func funcname(argumentLabel parameterName:Type)-> Return Type {
    //statements
}
```

让我们在下面的示例中看到它。

### 示例 7：不带参数标签的函数

```swift
func sum(a:Int, b:Int) -> Int {

    return a + b
}
let result = sum(a: 2, b: 3)
print("The sum is \(result)") 
```

运行该程序时，输出为：

```swift
The sum is 5
```

在上面的示例中，我们没有指定参数标签，因此在调用函数时它将默认参数名称`a`和`b`作为参数标签。

您可能会注意到，调用函数时，函数调用不是表达性/句子。 如果您可以将函数调用为：

```swift
let result = sum(of: 2, and: 3)
```

现在，将函数更改为：

### 示例 8：具有更好的函数调用但不作为参数名称的函数

```swift
func sum(of:Int, and:Int) -> Int {

    return of + and
}
let result = sum(of: 2, and: 3)
print("The sum is \(result)") 
```

现在，方法调用是可表达的。 但是，现在我们必须在`return of + and`中使用参数名称`of`和`and`来找到两个数字的和。 现在，这使得函数体不可读。 在函数体内使用`a`和`b`代替`of`和`and`。

为此，我们必须将参数标签明确定义为：

### 示例 9：带有参数标签的函数

```swift
func sum(of a :Int, and b:Int) -> Int {

    return a + b
}
let result = sum(of: 2, and: 3)
print("The sum is \(result)") 
```

在上面的程序中，该函数接受类型为`Int`的两个参数。 函数调用使用`of`和`and`的参数标签，将函数称为`sum(of: 2, and: 3)`而不是`sum(a: 2, b: 3)`有意义。

另外，函数体使用参数名称`a`和`b`代替`of`和`and`。

您也可以通过在参数名称之前写入`_`来省略参数标签。

```swift
func sum(_ a :Int, _ b:Int) -> Int {

    return a + b
}
let result = sum(2, 3)
print("The sum is \(result)") 
```

* * *

## 具有默认参数值的函数

您可以为函数中的任何参数提供默认值，方法是在该参数的类型之后为该参数分配一个值。 提供默认参数可让您在调用函数时忽略该参数。

如果在调用函数时未将值传递给参数，则使用其默认值。 但是，如果在调用时将值显式传递给参数，则使用指定的值。

```swift
func funcname(parameterName:Type = value) -> Return Type {
    //statements
}
```

### 示例 10：具有默认参数值的函数

```swift
func sum(of a :Int = 7, and b:Int = 8) -> Int {

    return a + b
}
let result1 = sum(of: 2, and: 3)
print("The sum is \(result1)")

let result2 = sum(of: 2)
print("The sum is \(result2)")

let result3 = sum(and: 2)
print("The sum is \(result3)")

let result4 = sum()
print("The sum is \(result4)") 
```

运行该程序时，输出为：

```swift
The sum is 5
The sum is 10
The sum is 9
The sum is 15 
```

在上述程序中，函数`sum(of a :Int = 7 , and b:Int = 8) -> Int`接受两个类型为`Int`的参数，但也指定了参数`a = 7`和`b = 8.`的默认值

如果在函数调用中以`sum(of: 2, and: 3)`的形式将值作为参数传递，则将使用 **2** 和 **3** 代替参数默认值。

但是，如果未将参数值传递为`sum()`，则将默认值 **7** 和 **8** 用作参数值。

## 具有可变参数的函数

可变参数可以接受零个或多个特定类型的值。 您可以通过在参数的类型名称后插入三个句点字符（...）来指定可变参数。

当需要在调用函数时将各种数量的输入值传递给参数时，通常使用可变参数。 例如，数字列表，字母列表等。

具有可变参数的函数的语法为：

```swift
func funcname(parameterName:Type...) -> Return Type {
    //statements
}
```

### 示例 11：具有可变参数的函数

```swift
func sum(of numbers:Int...) {
    var result = 0
    for num in numbers {
        result += num
    }
    print("The sum of numbers is \(result)")
}
sum(of: 1, 2, 3, 4, 5, 6, 7, 8) 
```

在上述程序中，函数`sum(of numbers:Int...)`接受类型为`Int`的可变参数。 可变参数可以接受多个以逗号分隔的值`sum(of: 1, 2, 3, 4, 5, 6, 7, 8)`。

作为可变参数传递的值 **1、2、3、4、5、6、7、8** 在函数体内可以作为`Int`类型的数组使用。 因此，我们可以在`for num in numbers`值中应用`for-in`循环。

运行该程序时，输出为：

```swift
The sum of numbers is 36
```

注意：内置`print()`函数的 Swift 也接受`Any`类型的可变参数。

`Any`代表 Swift 中的任何数据类型，例如`Int`，`Float`，`Double`，`String`等。

* * *

## 具有输入输出参数的函数

定义函数参数时，无法在体内修改函数参数。 因此，它们默认为常量。 让我们在示例中看一下：

```swift
func process(name:String) {
    if name == ""{
        name = "guest"
    }
}

```

上面的程序会导致编译时错误，因为您无法更改参数的值。

如果要让函数修改参数的值，则需要将参数定义为输入输出参数。 您可以通过将`inout`关键字放在参数类型的前面来编写输入/输出参数。

在后台，一个`in-out`参数具有一个值，该值传递到函数中，由函数修改，然后从函数中传递回以替换原始值。 因此，函数调用中传递的值不能为常数。 您必须将其声明为变量。

具有`inout`参数的函数的语法为：

```swift
func funcname(parameterName:inout Type) -> Return Type {
    //statements
}
```

### 示例 12：带有`inout`参数的函数

```swift
func process(name:inout String) { 
    if name == ""{
        name = "guest"
    }
}
var userName = ""
process(name: &userName)
print(userName) 
```

运行该程序时，输出为：

```swift
guest
```

在上面的程序中，我们声明了一个函数，该函数接受`inout`参数`name`，以便可以在函数体内更改/更改参数。

在将参数传递给`in-out`参数时，必须在变量名称之前直接使用`ampersand (&)`符号，以便可以通过函数对其进行修改。