Swift 函数中的默认可选参数

当我将 firstThing设置为默认 nil时,这将工作,如果没有 nil的默认值,我将得到一个错误,即在调用函数时缺少一个参数。

通过键入 Int?,我认为它是可选的,默认值为 nil,对吗?如果是这样,为什么没有 = nil它就不能工作呢?

func test(firstThing: Int? = nil) {
if firstThing != nil {
print(firstThing!)
}
print("done")
}
test()
171756 次浏览

可选参数和默认参数是两回事。

可选项是一个可以是 nil的变量,仅此而已。

当省略该参数时,默认参数使用 违约值,这个默认值是这样指定的: func test(param: Int = 0)

如果指定的参数是可选的,则必须提供该参数,即使要传递的值是 nil。如果你的函数看起来像这个 func test(param: Int?),你不能像这个 test()那样调用它。即使参数是可选的,它也没有默认值。

您还可以将两者结合起来,使用一个可选的参数,其中 nil是默认值,如下所示: func test(param: Int? = nil)

默认参数允许您在不传递参数的情况下调用函数。如果不传递参数,则提供默认参数。所以用你的代码,这个..。

test()

和这个完全一样:

test(nil)

如果像这样省略默认参数..。

func test(firstThing: Int?) {
if firstThing != nil {
print(firstThing!)
}
print("done")
}

那你就不能再这么做了。

test()

如果您这样做,您将得到您所描述的“缺少参数”错误。您必须每次都传递一个参数,即使该参数只是 nil:

test(nil)   // this works

Swift 不像 JavaScript 这样的语言,您可以不传递参数就调用函数,而且它仍然会被调用。因此,要在 Swift 中调用函数,需要 需要为其参数赋值。

参数的默认值允许您在调用函数时指定一个值而不指定它。这就是为什么在 test 声明中指定默认值时 test()可以工作的原因。

如果不包含默认值,则需要在调用中提供该值: test(nil)

另外,与这个问题没有直接关系,但是可能值得注意的是,您正在使用“ C + +”方式处理可能为空的指针,以便在 Swift 中处理可能为空的选项。下面的代码更安全(特别是在多线程软件中) ,并且它允许您避免强制展开可选的:

func test(firstThing: Int? = nil) {
if let firstThing = firstThing {
print(firstThing)
}
print("done")
}
test()

当您尝试将可选参数和该参数的默认值组合在一起时,就不那么复杂了,

func test(param: Int? = nil)

这两个想法完全相反。如果您有一个可选的类型参数,但是您也为它提供了默认值,那么它现在就不再是一个可选的类型了,因为它有一个默认值。即使默认值为零,Swift 也只是删除可选绑定,而不检查默认值是什么。

所以最好不要使用 nil 作为默认值。

“可选参数”表示“此参数的类型是可选的”。它并不意味着“这个参数是可选的,因此在调用函数时可以忽略它”。

术语“可选参数”似乎令人困惑。为了澄清,更准确的说法应该是“可选类型参数”,而不是“可选参数”,因为这里的“可选”一词只是用来描述参数值的类型,并没有其他意思。

如果您需要使用 bool 参数,只需要分配默认值即可。

func test(WithFlag flag: Bool = false){.....}

那么您可以使用没有或与 param 一起使用:

test() //here flag automatically has the default value: false
test(WithFlag: true) //here flag has the value: true

您正在将 Optional与缺省值合并。Optional接受值或者0。具有默认值允许在调用函数时省略参数。参数可以具有默认值,无论是否具有 Optional类型。

func someFunc(param1: String?,
param2: String = "default value",
param3: String? = "also has default value") {
print("param1 = \(param1)")


print("param2 = \(param2)")


print("param3 = \(param3)")
}

带有输出的示例调用:

someFunc(param1: nil, param2: "specific value", param3: "also specific value")


param1 = nil
param2 = specific value
param3 = Optional("also specific value")


someFunc(param1: "has a value")


param1 = Optional("has a value")
param2 = default value
param3 = Optional("also has default value")


someFunc(param1: nil, param3: nil)


param1 = nil
param2 = default value
param3 = nil

总结一下:

  • 类型(例如 String?)是一个 Optional可以是 nil,也可以包含 类型
  • 调用时可以省略具有默认值的参数 函数和默认值将被使用
  • 如果同时具有 Optional和缺省值,那么可以从函数调用中省略它,或者可以包含它,并且可以提供一个 nil 值(例如 param1: nil)

如果您希望能够使用或不使用参数调用 func,您可以创建第二个同名的 func来调用另一个。

func test(firstThing: Int?) {
if firstThing != nil {
print(firstThing!)
}
print("done")
}


func test() {
test(firstThing: nil)
}

现在您可以调用一个名为 test的函数,无论是否使用该参数。

// both work
test()
test(firstThing: 5)

默认值并不意味着数据类型的默认值。这里的默认值是定义函数时定义的平均值。 在函数中定义变量时,必须声明变量的默认值。

不要让问号愚弄了你!

Optionalenum,有两种情况:

@frozen public enum Optional<Wrapped> : ExpressibleByNilLiteral {


/// The absence of a value.
///
/// In code, the absence of a value is typically written using the `nil`
/// literal rather than the explicit `.none` enumeration case.
case none


/// The presence of a value, stored as `Wrapped`.
case some(Wrapped)
}

代码来自 Xcode 境内的原始编译源代码


当定义一个接受某些 Type参数的函数时,可以传递具有相同类型的 违约价值

在你的情况下

firstThing的类型是 Optional<Int>(也称为 Int?)。因此,如果你想让调用者有机会忽略这个参数,你需要 必须的为调用者完成这个任务并传递一个 默认值

通常我们需要 optional.none情况,所以我们可以这样做:

func test(firstThing: Optional<Int> = .none) { ... }

这和:

func test(firstThing: Int? = nil) { ... }

还有!

谁说我们的可选项的默认值是 nil?也许传递 nil意味着函数应该通过将它的值更新为‘ nil’来删除一些内容。所以不要以为是 “可选项的默认值为 nil”