Swift函数中的默认可选参数


107

当我设置firstThing为默认nil值时,它将起作用,没有默认值nilI时会出现错误,即调用该函数时缺少参数。

通过输入,Int?我认为它使其具有默认值的可选,nil对吗?如果是这样,为什么没有,它为什么不起作用= nil

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

1
考虑您可以编写func test(firstThing: Int = 4)Optional具有默认值的非参数。的Optional类型(这是?在一个类型名称膨胀至)是值类型; “可选参数”是在函数调用中可能出现或可能不出现的参数的不幸名称,无论其类型如何。
zneak

您使用哪个版本的Swift测试此代码?您的代码工作正常!!可选只是一个类型,默认参数正常工作与斯威夫特另一种类型
维克多西格莱尔

Answers:


210

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

Optional是可以是的变量nil

当您省略默认参数时,默认参数将使用默认值,该默认值的指定方式如下:func test(param: Int = 0)

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

您也可以将二者结合起来,有一个参数,它带有一个可选的地方nil是默认值,就像这样:func test(param: Int? = nil)


27
“如果指定的参数是可选的,则必须提供它”。太好了,
谢谢斯威夫特

8
@andrewtweber非常感谢您的幽默,但是对于新手来说,我认为澄清“可选”是指提供一种对象或价值可能会有所帮助。您不必这样做,您可以提供nil(表示没有对象或值)。您只需确定要选择的选项。
JD Sandifer

23

默认参数允许您在不传递参数的情况下调用函数。如果不传递参数,那么将提供默认参数。因此,使用您的代码,这...

test()

...与此完全相同:

test(nil)

如果省略这样的默认参数,则...

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

...那么您将无法再执行此操作...

test()

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

test(nil)   // this works

18

Swift与JavaScript等语言不同,您可以在不传递参数的情况下调用函数,并且该函数仍将被调用。因此,要在Swift中调用函数,您需要为其参数分配一个值。

参数的默认值使您可以在调用函数时分配一个值而不指定它。这就是为什么test()在测试的声明中指定默认值时有效的原因。

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

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

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

7

您正在将Optional默认值混为一谈。一个Optional接受一个值或零。具有默认值允许在调用函数时省略参数。参数可以具有或不具有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或可以包含Type的实例
  • 具有默认值的参数可能会从调用函数中省略,并且将使用默认值
  • 如果两者都Optional具有默认值,则可以从函数调用中将其省略,或者可以将其包括在内,并可以为其提供nil值(例如param1:nil)

我可以将默认参数添加为let或var之类的变量吗?谢谢
Yogesh Patel

@YogeshPatel不确定您的意思。
Chuck Krutsinger

就像var myName =“ Yogesh”。现在,我的功能就像1。func getFilterNames(name:string = myName){}这种方法对我不起作用。2. func getFilterNames(name:string =“ Yogesh”){}这种方法对我有用。但是我想要第一个,所以您能帮助我实现这一目标吗?非常感谢!
Yogesh Patel

@YogeshPatel我想你可能想要的是func getFilterNames(name: inout String){ },这将允许你修改中传递的名称。
查Krutsinger

不,不,先生。我不想修改我的参数。我只是想给我的参数默认值,但不喜欢静态的“ Yogesh”。我想像这样让name =“ Yogesh” dynamic func getFilterNames(name:string = name)做。得到这个先生?谢谢!
Yogesh Patel

3

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

术语“可选参数”似乎令人困惑。为了明确起见,用“可选类型参数”代替“可选参数”更为准确,因为此处的“可选”一词仅用于描述参数值的类型,仅此而已。


3

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

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

那么您可以不带参数也可以带参数一起使用:

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

对于对此表示反对的人,您可以改正错误的内容,以便其他人可以理解。
Niib Fouda

0

如果您希望能够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)

当仅将nil指定为参数的默认值时,为什么还要定义一个附加函数?
Peter Schorn

-1

当您尝试将可选参数和该参数的默认值组合在一起时,这一点都不麻烦。像这样,

func test(param: Int? = nil)

这两个是完全相反的想法。当您具有可选的类型参数但还提供默认值时,由于它具有默认值,因此现在不再是可选类型。即使默认值为nil,swift也会简单地删除可选绑定,而不检查默认值是什么。

因此,最好不要使用nil作为默认值。


1
这是不正确的。具有默认值(even nil)的可选选项没有错。
Brian Kendig

我的意思是,一旦变量具有默认值,就意味着它始终具有值,这不是可选的。
Shubham Naik

1
那是不对的,我不确定您要描述什么。我想您是在正确地说,一旦为变量分配了值,就将始终对其进行分配。您不能取消分配它(也不想),除非您取消分配它。如果您尝试在变量具有值之前使用它,则Swift会给您一个编译错误(如中所述var foo: String; print(foo))。但是具有默认值的函数参数是可选参数(您不必在函数调用中传递该参数),并且它也可以是可选类型(nil甚至可以将其分配为默认值)。
Brian Kendig

Optional本质上是<类型|联合类型。Nil>,即它可以具有指定类型或Nil类型。(假设swift拥有Unions,但它没有,但是我们在这里从概念上讲)。那么Int?= nil很好。
Shayne

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.