【问题标题】:Default optional parameter in Swift functionSwift 函数中的默认可选参数
【发布时间】:2016-05-18 17:02:37
【问题描述】:

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

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

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

【问题讨论】:

  • 考虑你可以写func test(firstThing: Int = 4):一个非Optional的参数,默认值。 Optional 类型(这是类型名称中的 ? 扩展为)是值类型; “可选参数”是在函数调用中可能出现也可能不出现的参数的不幸名称,无论其类型如何。
  • 你用什么版本的 Swift 来测试这段代码?你的代码工作正常!! Optional 只是一种类型,默认参数与 Swift 中的另一种类型一样工作正常

标签: swift function optional


【解决方案1】:

可选参数和默认参数是两个不同的东西。

Optional 是一个变量,可以是nil,就是这样。

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

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

您也可以将这两者结合起来,并有一个带有可选参数的参数,其中 nil 是默认值,例如:func test(param: Int? = nil)

【讨论】:

  • “如果你指定一个可选参数,你必须提供它”。太好了,谢谢斯威夫特
  • @andrewtweber 您的幽默值得赞赏,但对于新手来说,我认为澄清“可选”是指提供对象或值可能会有所帮助。您不必这样做,您可以提供 nil (表示不存在对象或值)。您只需要决定选择哪个选项。
【解决方案2】:

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

test()

...和这个完全一样:

test(nil)

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

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

...那么你不能再这样做了...

test()

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

test(nil)   // this works

【讨论】:

    【解决方案3】:

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

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

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

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

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

    【讨论】:

      【解决方案4】:

      您将Optional 与默认值混为一谈。 Optional 接受值或 nil。具有默认值允许在调用函数时省略参数。一个参数可以有一个默认值,无论是否为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)

      【讨论】:

      • 我可以将默认参数添加为变量,如 let 或 var 吗?谢谢
      • @YogeshPatel 不确定你的意思。
      • 像 var myName = "Yogesh"。现在,我的函数就像 1. func getFilterNames(name: string = myName){} 这种方法对我不起作用。 2. func getFilterNames(name: string = "Yogesh"){} 这种方法对我有用。但我想要第一个,所以请你帮我实现这一目标。非常感谢!
      • @YogeshPatel 我认为您可能想要的是func getFilterNames(name: inout String){ },它允许您修改传入的名称。
      • 不不,先生。我不想修改我的参数。我只想为我的参数提供默认值,但不像静态“Yogesh”。我想做这样的 let name = "Yogesh" dynamic func getFilterNames(name: string = name)。得到这个先生?谢谢!
      【解决方案5】:

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

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

      那么你可以不带参数也可以不带参数使用:

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

      【讨论】:

      • 对于不赞成这一点的人,您可以改正错误的地方,以便其他人理解。
      【解决方案6】:

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

      术语“可选参数”似乎令人困惑。澄清一下,说“可选类型参数”而不是“可选参数”更准确,因为这里的“可选”一词仅用于描述参数值的类型。

      【讨论】:

        【解决方案7】:

        如果您希望能够使用或不使用参数调用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 作为参数的默认值,为什么还要定义一个附加函数?
        【解决方案8】:

        别让问号骗了你!

        Optional 是一个 enum,它有两种情况:

        @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内部Optional的原始编译源代码


        当您定义一个接受一些Type 参数的函数时,您可以传递一个具有相同类型的默认

        你的情况

        firstThing 的类型是Optional&lt;Int&gt;(也称为Int?)。因此,如果您希望机会的调用者忽略该参数,您必须为调用者完成这项工作并传递一个默认值

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

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

        这完全一样:

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

        还有!

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

        【讨论】:

          【解决方案9】:

          当您尝试组合可选参数和该参数的默认值时,这有点棘手。像这样,

          func test(param: Int? = nil)
          

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

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

          【讨论】:

          • 这是不正确的。具有默认值的可选项(即使是nil)没有任何问题。
          • 我的意思是,一旦一个变量有一个默认值,它就不是一个可选的,因为它总是有一个值。
          • 这不是真的,我不确定您要描述什么。我认为您说得对,一旦变量分配了值,它将始终被分配;除非您取消分配它,否则您不能取消分配它(您也不想这样做)。如果你在变量有值之前尝试使用它,Swift 会给你一个编译错误(如var foo: String; print(foo))。但是具有默认值的函数参数是可选参数(您不必在函数调用中传递它),它也可以是可选类型(允许将nil 分配给它,即使作为默认值)。
          • 一个 Optional 本质上是一个联合类型 ,即它可以具有指定类型或 Nil 类型。 (假设 swift 有 Unions ,但它没有,但我们在这里讨论的是概念)。所以诠释? = nil 完全没问题。
          【解决方案10】:

          默认值不代表数据类型的默认值。这里的默认值是定义函数时定义的值。 我们必须在函数中定义变量时声明变量的默认值。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-07-20
            • 2011-09-20
            • 1970-01-01
            • 2016-08-30
            • 2011-11-06
            • 1970-01-01
            相关资源
            最近更新 更多