TLDR;
游乐场侧边栏/列将动态解析游乐场中的表达式,无论是分配给变量(可变/不可变)或只是“自由浮动”的未分配值。
您的第一个示例适用dynamicType
to a value,这将解决该特定值的类型 (true.dynamicType
: Bool.Type
).
另一方面,你的第二个例子适用dynamicType
to a variable(一个不可变的,但我会使用variable这里区别于value),它必须有一个具体类型,因此将解析为可以保存任何类型的包装值的类型(true
or false
) 也nil
(here, nil
具体来说是Optional<Bool.Type>.None
),无论变量实际持有什么值。因此,dynamicType
将决心Optional<Bool.Type>.Type
在你的第二个例子中。
Details
Playground侧边栏/列中显示的值一般遵循以下显示规则:
-
For an 任务表达式,侧栏中显示的值是分配的值,例如
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'. */
-
对于不包含赋值的表达式,侧栏中显示的值通常为表达式的结果, e.g.
true // shows 'true'
1 > 3 // shows 'false'
let c = 3
c // shows '3'
c.dynamicType // shows 'Int.Type'
在您的第一个示例(第 2-3 行)中,我们没有分配,并且游乐场将动态解析value解析之前表达式的 (/结果)dynamicType
那个值。由于我们正在处理可选的,value要么只是包装类型的值(在本例中,true
),或者该值为特定类型 .None
。即使操场上显示例如的结果let a: Int? = nil
就这样nil
在侧边栏中,显示的值实际上并不相同.None
(nil
)至于说let b: String = nil
- For
let a: Int? = nil
, the value of a
事实上是Optional<Int.Type>.None
,
- 而对于
let b: String? = nil
, the value of b
is Optional<String.Type>.None
考虑到这一点,自然而然地解决了dynamicType
的一个非nil
value将是具体的wrapped类型(在你的例子中,Bool.Type
自然是类型true
),而解决的dynamicType
of a nil
value 将包括一般可选信息和包装类型信息。
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
现在,如果你assign变量的值,自然该变量必须有一个具体的类型。由于我们分配的值在运行时可以是.None
or .Some<T>
,变量的类型必须是可以保存这两种情况的值的类型,因此,Optional<T.Type>
(不管变量是否成立nil
或非nil
价值)。这是您在第二个示例中展示的情况:dynamicType
of the variable(这里,不可变,但使用variable不同于value) isOk
是可以同时容纳两者的类型.None
and .Some<T>
,无论变量的实际值是多少,因此dynamicType
解析为这种类型;Optional<Bool.Type>.Type
.
将表达式括在括号中可以逃避 Swift Playground 的运行时自省吗?
有趣的是,如果在应用之前将表达式括在括号中.dynamicType
,然后游乐场侧边栏解析.dynamicType
包装表达式的type表达式的值,就好像它的实际值未知一样。例如。,(...)
in (...).dynamicType
被视为具有具体类型的变量而不是运行时解析的值。
/* .Some case (non-nil) */
foo?.bar // true
(foo?.bar).dynamicType /* Optional<Bool>.Type <-- as if (...)
is a _variable_ of unknown value */
/* .None case (nil) */
foo = nil
(foo?.bar).dynamicType /* Optional<Bool>.Type <-- as if (...)
is a _variable_ of unknown value */
我们还可以注意到,游乐场中任何用括号括起来的单独表达式都不会解析为任何内容(在侧栏中)。就好像我们逃避了侧边栏:如果将表达式包装在括号中(这可以解释为什么dynamicType
括在括号中的表达式将被解析,就好像游乐场无法使用这些表达式的运行时信息一样)
var a = 4 // shows '4'
(a = 2) // shows nothing; can't expand or get details in sidebar
老实说,我无法解释为什么会这样,并将其归类为 Swift Playground 的一个特性。