2015-10-05 2 views
2

Там, как представляется, несогласованность между предполагаемыми и динамическими типами значений в следующем коде (за пределами ожидаемого общности на неподвижной стороне):Прогнозные, статические и динамические типы вложенных опциями и их массивы в Swift

      // playground values in Xcode 7.0.1 (7A1001) 
          // (same behaviour in a release build) 

let oi: Int? = nil  // nil 
let ooi: Int?? = nil  // nil 

let os   = [oi, ooi] // [{nil}, nil] 
let anys: [Any] = [oi, ooi] // [nil, nil] 

oi == nil     // true 
ooi == nil     // true 

os[0] == nil    // false 
os[1] == nil    // true 

os[0].dynamicType   // Optional<Optional<Int>>.Type 
os[1].dynamicType   // Optional<Optional<Int>>.Type 

anys[0].dynamicType   // Optional<Int>.Type 
anys[1].dynamicType   // Optional<Optional<Int>>.Type 

(os[0] as Any).dynamicType // Optional<Optional<Int>>.Type 
(os[1] as Any).dynamicType // Optional<Optional<Int>>.Type 

os[0]!      // nil 
os[1]!      // fatal error: unexpectedly found nil while unwrapping an Optional value 

Например, не следует ли ожидать возврата Optional<Int>.Type?

ответ

0

Когда вы видите let os = [oi, ooi] // [{nil}, nil], фигурные скобки важны, потому что говорят, что первый элемент массива действительно имеет значение, и это значение равно нулю (это может показаться странным, я знаю).

Если вы делаете os.dynamicType, вы получите Array<Optional<Optional<Int>>>.Type.

Это может быть еще более ясно, с помощью следующего кода:

switch os[0] 
{ 
case .None: print("None") 
case .Some(let value): print("Some")  // "Some\n" 
    switch value 
    { 
    case .None: print("None")    // "None\n" 
    case .Some(let value): print("Some") 
    } 
} 

Это также объясняет, почему os[0]! равно nil и не врезаться.

На мой взгляд, легче подумать о вариантах как Struct, когда вы имеете дело с несколькими необязательными слоями.

+0

Спасибо за ответ. Увы, я не совсем уверен, что сделано «более ясно» в вашем примере кода. Обратите внимание, что вложенные опциональные элементы имеют совпадение по образцу (например, переключение на 'ooi' типа' Int ?? 'будет печатать' None' этим же кодом). Так что, если 'os [0]' соответствует шаблону как 'Int? 'Или' Int ??', поведение не должно наблюдаться ... – milos

Смежные вопросы