dynamicType необязательного связывания не совпадает с назначением
Необязательное сцепление всегда возвращает необязательное значение.
Чтобы отразить тот факт, что необязательное сцепление может быть вызвано для значения nil, результатом необязательного вызова цепочки всегда является необязательное значение, даже если запрашиваемое свойство, метод или индекс, возвращают неопциональное значение.
Почему, черт возьми, делает на детской площадке тип не по желанию?
let stringOptEmpty: String? = ""
stringOptEmpty?.isEmpty // is true
stringOptEmpty?.isEmpty.dynamicType // Bool.Type
Но следующий код
let isOk = stringOptEmpty?.isEmpty.dynamicType
isOk.dynamicType // Optional<Bool.Type>.Type
1 ответ
TLDR;
Боковая панель / столбец игровой площадки будет динамически разрешать выражения в игровой площадке, будь то значения, присвоенные переменным (изменяемые / неизменяемые) или просто "плавающие" неназначенные значения.
Ваш первый пример применим dynamicType
к значению, которое будет преобразовано в тип этого конкретного значения (true.dynamicType
: Bool.Type
).
Ваш второй пример, с другой стороны, относится dynamicType
в переменную (неизменяемую, но я буду использовать здесь переменную, чтобы отличаться от значения), которая должна иметь конкретный тип и, следовательно, будет преобразовываться в тип, который может содержать любой вид переносимых значений (true
или же false
) так же как nil
(Вот, nil
это, в частности, Optional<Bool.Type>.None
), независимо от значения переменной. Следовательно dynamicType
будет разрешать Optional<Bool.Type>.Type
в вашем втором примере.
подробности
Значение, отображаемое в боковой панели / столбце детской площадки, в целом соответствует следующим правилам отображения:
Для выражения присваивания значение, показанное на боковой панели, является назначенным значением, например
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'. */
Для выражения, которое не содержит присваивания, значение, показанное на боковой панели, обычно является результатом выражения, например
true // shows 'true' 1 > 3 // shows 'false' let c = 3 c // shows '3' c.dynamicType // shows 'Int.Type'
В вашем первом примере (строки 2-3) у нас нет назначения, и игровая площадка будет динамически разрешать значение(/ результат) выражения до разрешения dynamicType
этой стоимости. Поскольку мы имеем дело с опциями, значение является либо просто значением обернутого типа (в данном случае, true
), или значение зависит от типа .None
, Даже если игровая площадка показывает, например, результат let a: Int? = nil
как раз nil
на боковой панели показанное значение на самом деле не совпадает .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
значение будет включать в себя как общие необязательные, так и информацию обернутого типа
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
а также .Some<T>
, независимо от того, что фактическое значение переменной, и, следовательно, dynamicType
разрешает к этому типу; Optional<Bool.Type>.Type
,
Обтекание выражений в паратезах ускользает от самоанализа во время выполнения Swift Playground?
Интересно, что если выражение обернуто в парантезы до применения .dynamicType
, то боковая панель детской площадки разрешается .dynamicType
обернутого выражения в качестве типа выражения, как если бы его фактическое значение было неизвестно. Например, (...)
в (...).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.