可选链接返回始终可选值。
为了反映可以在nil值上调用可选链接的事实,可选链接调用的结果始终是可选值,即使您要查询的属性,方法或下标返回非可选值。
为什么heck在操场上的类型不是可选的?
let stringOptEmpty: String? = ""
stringOptEmpty?.isEmpty // is true
stringOptEmpty?.isEmpty.dynamicType // Bool.Type
但是以下代码是
let isOk = stringOptEmpty?.isEmpty.dynamicType
isOk.dynamicType // Optional<Bool.Type>.Type
答案 0 :(得分:4)
操场边栏/列将动态解析操场中的表达式,无论是分配给变量(mutables / immutables)的值还是仅仅是“自由浮动”的非指定值。
您的第一个示例将dynamicType
应用于值,该值将解析为该特定值的类型(true.dynamicType
:{{1 }})。
另一方面,你的第二个例子将Bool.Type
应用于变量(一个不可变的,但我会在这里使用变量来区别于< em> value ),它必须具有具体类型,因此将解析为可以包含任何类型的包装值(dynamicType
或true
)以及{{1 (此处,false
,具体而言,nil
),无论变量实际保持什么值。因此,nil
将在您的第二个示例中解析为Optional<Bool.Type>.None
。
游乐场侧栏/栏中显示的值通常遵循以下显示规则:
对于赋值表达式,侧栏中显示的值是指定的值,例如
dynamicType
对于不包含赋值的表达式,侧栏中显示的值通常是表达式的结果,例如
Optional<Bool.Type>.Type
在您的第一个示例(第2-3行)中,我们没有赋值,并且在解析var a = 4 // shows '4'
a = 2 // shows '2'
let b: () = (a = 3)
/* shows '()': the _value_ assigned to 'b', which is the _result_
of the assignment 'a = 3', to which a _side effect_ is that 'a'
is assigned the value '3'. */
之前,操场将动态解析表达式的值(/ result)那个价值。由于我们正在处理选项,因此值或者只是包装类型的值(在本例中为true // shows 'true'
1 > 3 // shows 'false'
let c = 3
c // shows '3'
c.dynamicType // shows 'Int.Type'
),或者值是类型特定的 dynamicType
。即使操场上显示例如{/ 1}}的结果仅为侧边栏中的true
,显示的值实际上与.None
let a: Int? = nil
nil
不同{/ 1}} p>
.None
,nil
的 值 实际上是let b: String = nil
,let a: Int? = nil
,a
的 值 为Optional<Int.Type>.None
考虑到这一点,很明显,非let b: String? = nil
值的已解决b
将是具体的包裹类型(在例如,Optional<String.Type>.None
自然是dynamicType
的类型,而nil
值的已解析Bool.Type
将包括常规可选和包装类型信息。
true
现在,如果将值赋值给变量,那么变量必然具有一个具体类型。由于我们在运行时分配的值可以是dynamicType
或nil
,因此变量的类型必须是可以保存这两种情况的值的类型,因此,{{ 1}}(忽略变量是保持struct Foo {
let bar: Bool = true
}
var foo: Foo? = Foo()
/* .Some<T> case (non-nil) */
foo?.bar // true <-- _expression_ resolves to (results in) the _value_ 'true'
foo?.bar.dynamicType // Bool.Type <-- dynamic type of the _result of expression_
true.dynamicType // Bool.Type <-- compare with this
/* .None case (nil) */
foo = nil
foo?.bar.dynamicType // nil <-- _expression_ resolves to the _value_ 'Optional<Foo.Type>.None'
Optional<Foo.Type>.None.dynamicType
// Optional<Foo.Type>.Type <-- compare with this
还是非.None
值。这是您在第二个示例中显示的情况:变量的.Some<T>
(此处为不可变,但使用变量与不同>值)Optional<T.Type>
是可以同时包含nil
和nil
的类型,无论变量的实际值是什么,因此dynamicType
可以解析这种类型; isOk
。
有趣的是,如果在应用.None
之前将表达式包装在parantheses中,那么操场侧边栏会将包装表达式的.Some<T>
解析为表达式的 type ,如如果它的实际值是未知的。例如,dynamicType
中的Optional<Bool.Type>.Type
被视为具有具体类型而不是运行时解析值的变量。
.dynamicType
我们可以进一步注意到,在操场上的parantheses中包含的任何单独的表达都不会解析为任何东西(在侧边栏中)。就像我们逃避侧边栏:s运行时内省是否将表达式包装在parantheses中(这可以解释为什么包含在parantheses中的.dynamicType
表达式将解析为操场无法使用这些表达式的运行时信息)
(...)
Tbh,我无法解释为什么会这样,并将其归类为Swift游乐场的特色。