Почему элемент массива downcast в Swift? - PullRequest
0 голосов
/ 21 января 2020

Почему я должен понижать элемент массива в Swift, если подкласс элемента массива известен?

 > class B {let t: String = "-B-"}
 > class B1:B {let t1: String = "-B1-"}
 > class B2:B {let t2: String = "-B2-"}
 > let bunch = [B(), B1(), B2()]

Как и ожидалось:

 > print(type(of:bunch))
 Array<B>

Подкласс каждый элемент массива известен:

 > for item in bunch {print(type(of:item))}
 B
 B1
 B2

Тем не менее (как задокументировано) мы не можем получить доступ к члену подкласса элемента, и нам необходимо понизить класс:

> if bunch[1] is B1 {let b1 = bunch[1] as! B1; print(b1.t1)} 
-B1-

потому что это не работает:

> bunch[1].t1
error: repl.swift:17:6: error: value of type 'B' has no member 't1'; did you mean 't'?

Почему Swift может определить подкласс, используя тип (of :), но не может вывести его при доступе к члену в этом подклассе? Это ошибка, историческое c похмелье или я что-то упустил?

Ответы [ 2 ]

1 голос
/ 21 января 2020

Массивы Swift - это коллекции элементов одного типа . Тип массива

let bunch = [B(), B1(), B2()]

выводится как [B], поскольку B является «ближайшим общим суперклассом». Из этих трех элементов. Следовательно, bunch[1] имеет тип B, а не B1. Вот почему bunch[1].t1 не компилируется.

Конечно, вы можете напечатать фактический тип элемента массива во время выполнения с помощью type(of:) или проверить его по B1. Последнее лучше сделать с необязательной привязкой:

if let b1 = bunch[1] as? B1 {
    print(b1.t1)
}
1 голос
/ 21 января 2020

Простой ответ заключается в том, что как только вы объявите массив типа B, компилятор обрабатывает все элементы в массиве как тип B и не будет автоматически выводить методы на основе каких-либо имеющихся подклассов. Кажется, вы задаетесь вопросом, почему компилятор / массив не настолько умен, чтобы определить класс объявленного массива let, хотя теоретически это может быть так. Я не уверен, что многие языки поддерживают такую ​​функцию, в любом случае вы можете сделать то же самое, просто развернув ее, как и вы, поскольку в этом случае вы это знаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...