简体   繁体   English

如何在函数中指定参数可以在Swift中为nil

[英]How to specify the parameter in a function can be nil in Swift

I know we need to define the parameter of function in Swift to be neither implicit unwrapped optional or optional, to make it non-nil. 我知道我们需要在Swift中定义函数的参数,既不是隐式展开的可选参数,也不是可选的,以使其成为非零。 However I am not sure what is more conventional between implicit unwrapped optional or optional. 但是我不确定隐式展开的可选或可选之间更常见的是什么。

I am watching WWDC 2014 Swift interoperability in depth and a bit confused with two examples shown in the slides. 我正在深入观察WWDC 2014 Swift互操作性,并且与幻灯片中显示的两个示例有点混淆。 Basically it is about whether we should use implicit optional or unwrap parameters when defining function. 基本上它是关于在定义函数时是否应该使用隐式可选或解包参数。


Example from Video 视频示例

Below is the screenshot from that WWDC 2014 Swift interoperability in depth (At 09:01) 下面是WWDC 2014 Swift互操作性的截图(在09:01) 在此输入图像描述 And the quote from the speaker is 而发言者的话是

You see again this is an implicit unwrapped optional, so that you can pass a nil block in here. 你再次看到这是一个隐式的unwrapped可选项,因此你可以在这里传递一个nil块。

Notice here both url and completionHandler are implicit unwrapped optionals, and we can pass in nil into it. 请注意, urlcompletionHandler都是隐式解包的选项,我们可以将nil传入其中。 All good! 都好!


Example from Header file 头文件中的示例

However when I check UIKit UITableViewCell, I find most of the methods are defined with optional parameters, such as 但是当我检查UIKit UITableViewCell时,我发现大多数方法都是用可选参数定义的,例如

    init(style: UITableViewCellStyle, reuseIdentifier: String?)

And basically it is suggesting those parameters can be nil too. 基本上它表明这些参数也可以是零。

Seems like both ? 好像两者都有 and ! 而且 try to suggest the same thing (it can be nil ). 试着建议同样的事情(它可以是 )。

I understand that ? 我明白了吗? means we will wrap whatever value to optional value (even for nil), and ! 意味着我们将任何值包装到可选值(即使是nil),并且 means we will unwrap it if what is passed in is an optional value. 意味着如果传入的内容是可选值,我们将解包它。 But I am not sure whether we should use ! 但我不确定是否应该使用 or ? 还是 . And which is conventional? 哪个是传统的?


Update 更新

Looks like the video from WWDC 2014 is not quite correct or out-dated . 看起来WWDC 2014的视频不太正确或过时 Screenshot from the video shows UIDocument header file, which was different from the current UIKit header. 视频的屏幕截图显示了UIDocument头文件,它与当前的UIKit头不同。 It looks like at that time, all of them were defined as ! 看起来那个时候,所有这些都被定义为 . But now it is either ? 但是现在它要么 or plain type. 或普通类型。

WWDC 2014 Swift interoperability in depth (At 16:25) WWDC 2014 Swift深度互操作性(16:25)

WWDC的截图

Current header file 当前头文件

当前头文件的屏幕截图

  • ? is a shortcut for Optional<T> type Optional<T>类型的快捷方式
  • ! is a shortcut for ImplicitlyUnwrappedOptional<T> type ImplicitlyUnwrappedOptional<T>类型的快捷方式

Both types implement NilLiteralConvertible. 这两种类型都实现了NilLiteralConvertible。 This mean they have init(nilLiteral: ()) and can be initialized by Void . 这意味着他们有init(nilLiteral: ())并且可以通过Void初始化。 This could be syntatically-sugard in code by compiler into regular assignement of nil to a NilLiteralConvertible variable. 这可以通过编译器在代码中以合成方式进行, NilLiteralConvertible nil定期分配给NilLiteralConvertible变量。 Here are some code lines that from compiler standpoint mean the same: 以下是从编译器角度来看的一些代码行:

 let sweetOptionalInt: Int? = nil
 let semiSweetOptionalInt: Optional<Int> = nil
 let unsweetenedOptionalInt: Optional<Int> = Optional<Int>(nilLiteral: Void)

The same is true for ImplicitlyUnwrappedOptional . ImplicitlyUnwrappedOptional也是如此。

So both could be initialized by nil , but behaviors of these types are different: 所以两者都可以用nil初始化,但这些类型的行为是不同的:

  • ImplicitlyUnwrappedOptional do unwrapping for you with an assumption when you do a call object is already provided (but could be nil before), so if it is not then application will crash with a runtime error. ImplicitlyUnwrappedOptional会为您提供一个假设,当您已经提供了一个调用对象时(但之前可能是nil),所以如果不是,那么应用程序将因运行时错误而崩溃。
  • Optional will require you to provide information how to unwrap variables. Optional将要求您提供有关如何解包变量的信息。

As for interoperability while ago Objective-C didn't have a way to express nullability of variables. 至于之前的互操作性,Objective-C没有办法表达变量的可空性。 This is why most of APIs was converted with ! 这就是为什么大多数API都被转换了! that stands for "proceed further if you dare" Recently Apple introduced nullability annotations for Objective-C. 代表“如果你敢于进一步继续下去”最近Apple推出了针对Objective-C的可空性注释。 Apple augumented their APIs with these annotations, so now it is easier and safer to use methods with an extra nullability guidance in Swift. Apple使用这些注释来增加他们的API,因此现在使用Swift中具有额外可空性指导的方法更容易,更安全。

You aren't quite right. 你不太对劲。 "!" “!” is the "force unwrap" operator. 是“强制解包”操作员。 It says "This is an optional, but I guarantee that when this code runs, it won't be nil." 它说“这是一个可选的,但我保证当这个代码运行时,它不会是零。” If you are wrong, you crash. 如果你错了,你会崩溃。

if you are writing a function that takes a parameter that can be legitimately nil, use "?", which makes it an Optional. 如果你正在编写一个带有合法nil参数的函数,请使用“?”,这使它成为一个可选项。 Then in the code of your function, you have to handle the case where it is nil. 然后在函数的代码中,你必须处理它为零的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM