当前位置: 首页 > 面试题库 >

为什么非可选的Any可以保持nil?

艾自强
2023-03-14
问题内容

在Swift中,我可以声明一个类型常量Any并将其String放入。

let any: Any = "hello world"

好。另一方面,我 不能 输入nil值,any因为它不是可选的。

let any: Any = nil

error: nil cannot initialize specified type 'Any' (aka 'protocol<>')
let any: Any = nil
              ^

完善。但是为什么编译器允许我编写以下代码?

let couldBeNil: String? = nil
let any: Any = couldBeNil
print(any) // nil

是否不Any遵循Swift规则,只能使用Optional var / let填充nil

经过Xcode Playground 7.2 + Swift 2.1.1的测试


问题答案:

TL; DR; swift中的可选项由编译器转换为Optional枚举实例,并且由于Any可以映射到任何值,因此可以用于存储可选项。

Swift如何表示可选内容?它通过映射SomeType?Optional枚举的具体实现来实现:

Int? => Optional<Int>
String? => Optional<String>

简化的Optional外观声明如下:

enum Optional<T> {
    case none    // nil
    case some(T) // non-nil
}

现在,类型变量Any可以保存枚举值(或任何其他类型的值,甚至是元类型信息),因此它应该可以保存例如nilString,aka
String?.none,aka Optional<String>.none

让我们看看会发生什么。正如Optional声明所看到的,它nil对应.none于所有类型的枚举情况:

nil == Optional<String>.none // true
nil == Optional<Int>.none    // true
[Double]?.none == nil        // also true

因此,从理论上讲,您应该能够分配nil给声明为的变量Any。尽管如此,编译器仍不允许这样做。

但为什么不编译器让你指定nil一个Anyhtml" target="_blank">变量?这是因为它无法推断要映射.none枚举大小写的类型。Optional是一个通用枚举,因此它需要一些东西来填充T通用参数,而plain
nil太宽泛了。.none应该使用哪个值?一个来自Int,一个来自String,另一个?

这给出了支持以上段落的错误消息:

let nilAny: Any = nil // error: nil cannot initialize specified type 'Any' (aka 'protocol<>')

以下代码有效,并且等效于分配一个nil

let nilAny: Any = Optional<Int>.none

,因为上述Any变量实际上持有Optional枚举的有效值。

间接分配也起作用,因为幕后将nil其转换为Optional<Type>.none

var nilableBool: Bool? // nilableBool has the Optional<Bool>.none value
var nilBoolAsAny: Any = nilableBool // the compiler has all the needed type information from nilableBool

与其他语言不同,Swift
nil对应于一个具体值。但是它需要一种类型,以便编译器知道Optional<T>.none应该分配哪种类型。我们可以认为该关键字提供了糖语法。



 类似资料:
  • 问题内容: 它以空字符串开头,而不是nil。即使将其显式设置为nil,它仍然是一个空字符串。我不明白 也许通过分配nil使其易于清除?用它编写代码很麻烦。 问题答案: 这是历史性的事情。空字符串和字符串之间没有任何区别。在Objective- C中,无需在两者之间进行区别,因为您可以在Objective-C中调用方法。 同样,在Objective-C中也无法阻止用户分配给属性。生成的合同可以是可选

  • 当使用Java8类时,有两种方法可以将值包装到Optional中。 我理解是使用的唯一安全方法,但为什么?为什么不直接使用

  • 我想做一个api,可以接受两个路径变量,其中一个可以是可选的。在这篇文章中,他们说我们可以通过使用Optional来实现这一点,但这不起作用。 这是我的控制器 在斯威格的这幅图中,需要两个参数,即使第二个参数有 由于我使用JHipster生成了我的Spring启动应用程序,当我没有给出可选参数的值时,在postman上。我得到了这个错误 如果有人能帮助我理解为什么会发生这种情况和/或我如何解决它,

  • 问题内容: 我读苹果文档 ,当我发现这句话: 本类仅包含一个属性:。 此属性存储对应用程序窗口的引用。此窗口表示应用程序视图层次结构的根。这 是绘制所有应用程序内容的地方。请注意,window属性是 可选的 ,这意味着 在某些时候它可能没有任何值(为nil ) 。 我不明白的是:为什么此属性有时可能为零? 变成零的情况是什么? 问题答案: 当您关闭应用程序时,您的应用程序仍可以接收静默通知 或在后

  • 为什么可选在线? 当可选值包含“nil”时,必须将可选类型“Int?”的值解包为“Int”类型的值,并使用“?”合并,以提供默认值,当可选值包含“nil”时使用“!”强制解包以中止执行 所以这修复了它: 如果我将其分解,则会在添加<code>let index</code>时发生更改。。。。 OK -这将返回first的总计数,total不是可选的: 确定-此枚举和总计不是可选的: 错误 - 这会

  • 学JSONP的时候发现是通过script来访问非同源的网址的,但是浏览器有同源策略不是嘛,学的有点迷糊了,请各位指点。 最好希望能提供MDN或者官方的出处