Быстрые массивы могут содержать только один тип. Когда вы объявили:
let arr = [1, "a", 2.88]
Swift сделал arr
типа [NSObject]
. Вы можете проверить это на Вариант -clicking на arr
для просмотра его типа. Это работает только потому, что у вас есть Фонд импортирован (ваш import UIKit
импорт Foundation
). Попробуйте удалить import UIKit
.
Затем значения 1
и 2.88
были преобразованы в NSNumber
и "a"
к NSString
так, что они могут быть сохранены в этом массиве, потому что [NSObject]
Int
с, String
с, и Double
ы не NSObjects
. NSNumber
и NSString
являются подклассами NSObject
. Swift выбирает наиболее ограничительный тип для массива. Если бы ваш массив был [1, true, 2.88]
, тип массива был бы [NSNumber]
.
Интересная вещь о NSNumber
заключается в том, что это контейнер объектов, который обертывает множество разных типов. Вы можете положить Int
и вынуть Double
. Таким образом, это вводит в заблуждение, когда вы тестируете его с помощью is
. Он отвечает «истинному» значению: «Я могу быть таким, если вы хотите».
import Foundation
let n: NSNumber = 3.14
print(n is Int) // "true"
print(n is Double) // "true"
print(n is Bool) // "true"
print(n as! Int) // "3"
print(n as! Double) // "3.14"
print(n as! Bool) // "true"
Примечание: Если бы вы объявили о своей arr
быть [Any]
, то это сработало бы, как вы ожидали:
let arr:[Any] = [1, "a", 2.88]
let last = arr.last
if last is Int {
print("The last is Int.")
} else {
print("The last is not Int.") // "The last is not Int."
}
Но Свифт не собирается создать массив типа Any
для вас, если вы не спросите явно (потому что, откровенно говоря, это мерзость на строго типизированном языке). Вероятно, вам следует пересмотреть свой дизайн, если вы обнаружите, что используете [Any]
.
Единственная причина Swift создает [NSObject]
когда Foundation импортируется, чтобы сделать нашу жизнь проще при вызове какао и Cocoa Touch API. Если для такого API требуется передать NSArray
, вы можете отправить [1, "a", 2.88]
вместо [NSNumber(integer: 1), NSString(string: "a"), NSNumber(double: 2.88)]
.
> Затем значения преобразуются в 'NSNumber'. Но когда я проверяю тип переменной 'last', это' NSObject? ', А не 'NSNumber'. – pacification
'last' возвращает необязательную переменную типа, хранящегося в массиве. Массив - это '[NSObject]'. Этот конкретный экземпляр содержит два 'NSNumber' и' NSString', которые являются подклассами 'NSObject'. – vacawama
Кажется, что компилятор никогда не выводит типы как 'Any' или' [Any] ', поэтому единственный возможный способ вывести тип этого массива (если импортируется' Foundation') - это преобразование 'NSNumber', а затем использовать '[AnyObject]' или '[NSObject]'. Без 'Foundation' компилятор вызовет ошибку. Вы все равно можете использовать '[Any]' явно. – Sulthan