Я был действительно смущен, обнаружив, что следующий код просто отказывается аварийно завершать работу с типичным исключением « неожиданно найден ноль при развертывании необязательного значения », которое можно ожидать при принудительном развертывании bar
.
struct Foo {
var bar: Bar?
}
struct Bar {}
var foo = Foo()
debugPrint(foo.bar) // nil
debugPrint(foo.bar!.dynamicType) // _dynamicType.Bar
Кажется, dynamicType
каким-то образом способен вернуться к определенному типу bar
- без сбоев.
Обратите внимание, что это происходит, только когда Bar
определяется как тип значения (как @dfri говорит ), Foo
является struct
или final class
(как отмечает @MartinR ) & foo
является изменчивым.
Первоначально я считал, что это может быть просто оптимизация компилятора из-за того, что тип bar
известен во время компиляции, поэтому поэтому развертывание силы могло быть оптимизировано, но оно также аварийно завершается, когда Bar
] определяется как final class
. Кроме того, если я установлю «Уровень оптимизации» на -Onone
, он все равно будет работать.
Я склонен думать, что это странная ошибка, но хотел бы получить подтверждение.
Это ошибка или функция с dynamicType
, или я просто что-то здесь упускаю?
(Использование Xcode 7.3 с Swift 2.2)
Это все еще воспроизводимо (с еще более минимальным примером) в Swift 4.0.3:
var foo: String?
print(type(of: foo!)) // String
Здесь мы используем dynamicType
' s преемник, type(of:)
, чтобы получить динамический тип; и, как и в предыдущем примере, он не падает.