- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在 Apple 关于可空性的博客中,他们提到了这一点:
"...in Swift there’s a strong distinction between optional and non-optional references, e.g. NSView vs. NSView?, while Objective-C represents boths of these two types as NSView *. Because the Swift compiler can’t be sure whether a particular NSView * is optional or not, the type is brought into Swift as an implicitly unwrapped optional, NSView!"
最佳答案
Apple 的框架并没有什么特别之处。一开始,你在 Swift 中从 Objective-C 使用的所有东西(每个对象)都是一个隐式解包的可选项。那是因为 Objective-C 中的每个指针都可能返回 nil
.
事实上,即使在Objective-C可空性注解的时代,一个方法被注解为nonnull
也不是完全不可能的。可以返回 nil
. Objective-C 不强制执行可空性规则,它只是提供了一种注释代码的方法,以便在 Swift 中使用它应该更安全。就 Apple 的框架而言,我敢打赌你不会遇到这个问题。或者,如果您这样做了,下一版本的 Xcode 将修复它。
但同样,来自 Objective-C 库和框架的隐式解包选项并没有什么特别之处。隐式解包的可选项告诉您的唯一一件事是框架作者尚未努力注释他们的库(您不能将隐式解包的可选项留在带注释的库中)。 是的,这些隐式展开的选项可以是 nil
它们可能会使您的应用程序崩溃。
在 Apple 的情况下,如果出于某种原因,您在不同的项目上使用 Xcode 7 和 Xcode 6,如果您采用 Xcode 7 的更新注释已声明为非可选的内容,则假设 Xcode 中隐式解包的可选版本6永远不会nil
可能会解决。但是,如果您采用 Xcode 7 中的可选内容,则假设 Xcode 6 中隐式解包的版本永远不会是 nil
很可能会导致您的应用程序崩溃。
最终,在 Swift 中,我们使用隐式解包的可选项应该很少。隐式解包选项的主要用途应该主要用于在类初始化返回之前无法设置的类属性(例如, View Controller 中的 @IBOutlets
)。否则,它们很容易成为 Stack Overflow 上众多“意外发现为零”问题的来源。
对于“为什么返回一个隐式展开的可选项而不是可选项?”的问题,有几点……
首先,这是一个语言设计问题。我不是 Objective-C 或 Swift 语言设计团队的成员,而且这些团队中的任何人都不可能停下来回答这个问题......
其次,这就是语言被设计为互操作的方式。任何没有添加可空性注释的 Objective-C 文件都将被视为在 Swift 中一切都是隐式解包的可选项。
第三,隐式可选的原因是它减少了很多if let
的冗长。可选将需要的等语句,但不保证变量实际上是 non-nil
.造成这种情况的大部分原因可能是因为您认为这些方法中的大多数实际上永远不会返回 nil
.
第四,如果你知道哪些有机会成为nil
哪些没有,你实际上可以继续编写你的 Swift 代码,这种方式既可以处理对 Objective-C 代码将被注释的方式做出假设。
例如,对于隐式解包的可选项,当然,您可以将其视为非可选项,并删除一些与解包相关的次要冗长。
此外,如果您认为它可能是 nil
,所有可选的解包内容仍然可以使用它。
例子:
override func someFunc(implicitVal: String!) -> String {
return implicitVal ?? "It was nil!"
}
override func someOtherFunc(implicitVal: String!) -> String {
return implicitVal
}
nil
.
关于Swift 在可空性可用之前使用 Implicitly Unwrapped Optional,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30880969/
我经常使用 var options = options || {} 作为默认为空对象的方式。它通常用于初始化选项对象,以防它未在函数调用的参数中传递。 问题是我在几个地方(博客文章、源代码)读到opt
我是Python中Rust的新手。这是我学习Rust的第四天。 在第一个问题Type casting for Option type之后,我有一个跟语法match和所有权概念有关的后续问题。 首先,我
我正在学习 Ray Wenderlich。我遇到了闭包语法错误。我想知道 Xcode 提示是什么意思? Xcode 报告如下: /Users/.../FlickrPhotosViewControlle
使用 Python 编写命令行界面 (CLI) 时 click library , 是否可以定义例如三个选项,其中仅当第一个(可选)未设置时才需要第二个和第三个选项? 我的用例是一个登录系统,它允许我
我有一个这样的 JPA 查询。 PersonRepository.java public Optional> findByStatus(int status); 人员服务.java System.ou
我遇到了很多地方,我有类似的东西 def f(s: String): Option[Long] = ... def g(l: Long): IO[Option[Wibble]] = ... val a
我有一个results: List[Future[Option[T]]]其中包含(并行)计算。 我想获得第一个非None尽快出结果,或者返回None如果所有计算都返回 None . 目前,我正在这样做
我正在尝试加载一个简单的 Listbox组件来自 @headlessui/react . 选择.tsx type Option = { id: number name: string
如何将Future[Option[Future[Option[X]]]]转换为Future[Option[X]]? 如果它是 TraversableOnce 而不是 Option 我会使用 Futur
Haskell、Rust 等语言提供了一个 Maybe 或 Option 类型。即使在 Java 中,也有一个 Optional 现在打字。 为简单起见,我将在剩下的问题中将此类型称为“选项类型”。
当我尝试在 SQL 中存储一个 XML 而不是一个空元素时,SQL 只是更改它并仅使用一个元素标签来存储它。例如,要存储的 XML 是: ROGER 然后Sql存起来就好了
使用这个非常好的命令行解析器 Argo(仅 header C++ 库)我遇到了一个小问题。请参阅:https://github.com/phforest/Argo Argo 返回:'Error: Un
我是来自 Java 背景的 Scala 新手,目前对考虑 Option[T] 的最佳实践感到困惑. 我觉得用 Option.map只是更实用和美观,但这不是说服其他人的好理由。有时, isEmpty
这个问题在这里已经有了答案: Chaining Optionals in Java 8 (9 个回答) Optional orElse Optional in Java (6 个回答) Functio
Optional::stream如果存在,则返回一个包含该值的 Stream,否则返回一个空流。所以对于 Stream> optionals , optionals.flatMap(Optional:
我使用箭头键作为输入,在 printf 菜单中上下移动 printf 箭头(“==>”)。 我正在使用一个函数来计算箭头应该在的位置,并使用 switch case 和 printf("\n==>")
这个问题在这里已经有了答案: What does the construct x = x || y mean? (12 个答案) 关闭 9 年前。 如我的问题标题所述,我最近偶然发现了这个变量声明:
这个问题在这里已经有了答案: BackboneJS: What is options || (options = {}); in Backbone source code (1 个回答) 关闭 8
我有这个简单的语法: word = Word(alphanums + '_') with_stmt = Suppress('with') + OneOrMore(Group(word('key') +
使用 Cucumber 和 SitePrism 编写测试,我在页面上有以下 HTML... Select a Status Active Product Inactive Prod
我是一名优秀的程序员,十分优秀!