@driverx18

В чем отличие данной записи с дженериком и без?

Нашел урок по дженерикам, автор показывает пример где их можно юзать. Цитирую пример:

func printEvery<T>(_ array: [T]) {
    for element in array {
        print(element)
    }
}

Чтобы обойти массив любого типа и вывести любой элемент вместо того, чтобы якобы не делать функции: printInts, printStrings (из-за строгой типизации).
И все это работает, но что нам мешает сделать такую же функцию без дженерика, а с типом Any?

func printEvery(_ array: [Any]) {
    for element in array {
        print(element)
    }
}

Этот пример также работает.
В свифте новичок, может вопрос покажется глупым.
  • Вопрос задан
  • 144 просмотра
Решения вопроса 1
doublench21
@doublench21 Куратор тега Swift
Два типа Anyи AnyObject являются так называемыми Nonspecific types. Неспецифичные типы служат указателем компилятору о возможности хранения любого типа. НО за такую возможность нужно платить и Вы платите:

Во-первых отсутствием информации о типе на момент компиляции, вы не можете вызвать, скажем некоторое св-во у String, даже зная, что присвоенная переменная на самом деле является типом String. У вас просто не будет такой информации ровно до тех пор, пока вы не преобразуете этот тип обратно.
Конечно во время выполнения Swift прекрасно понимает, какой именно тип находится в переменной типа Any, но это только во время выполнения кода, на момент компиляции информация об этом отсутсвует.

Во-вторых вы платите скоростью, при работе с такими типами. У компилятора нету информации о типе, а значит он не может произвести необходимые оптимизации.

Функция print(_:separator:terminator:) получает информацию о том, что вывести в консоль, исходя из того, что все стандартные типы реализуют протоколы CustomStringConvertible, CustomDebugStringConvertible,CustomReflectable в реализации которых содержится информация о типе(текстовая). Если у типа нет реализации этих протоколов, print(_:separator:terminator:) выводит просто название типа.

Более того, вы всегда можете вывести так называемый дамп у абсолютного любого типа в консоль посредством функции dump(_:name:indent:maxDepth:maxItems:).

За более подробной информации о всех возможностях и разновидностях функций для работы с Debugging and Reflection можно глянуть тут

------------------------------------------------------------------------------------------------------------------------

Дженерики же - это просто заместители(placeholders) типов. На момент компиляции, компилятор вместе вашего заместителя, скажем T подставит конкретный тип, скажем String. Что в свою очередь приводит к тому, что у дженериков отсутствуют проблемы указанные выше. (Даже моё "во-первых" у дженериков отсутствуют, если вы накладываете на них ограничения. )

------------------------------------------------------------------------------------------------------------------------

P.S. На самом деле Дженерики одна из самых прекрасных и Сильных сторон языка Swift, и моя жалкая попытка вам пояснить - не объясняет должном счётом ничего. Изучайте их.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
ivanvorobei
@ivanvorobei
iOS разработчик, канал https://t.me/sparrowcode
Но что нам мешает сделать такую же функцию без дженерика, а с типом Any?

Ничего. Так же можно использовать forEach. Я не говорю что дженерики не нужны, только ответил вопрос.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы