C objective vs swift: Яблочное сравнение: Swift vs Objective-C | GeekBrains

Содержание

Яблочное сравнение: Swift vs Objective-C | GeekBrains

https://d2xzmw6cctk25h.cloudfront.net/post/879/og_cover_image/08c21a87b103091e11a08ec78d994e3f

Язык Swift по замыслу его создателей призван не только заменить Objective-C в качестве базового для разработки приложений для iOS, но и заменить C во всех остальных сферах, в том числе IoT. Но если бы Swift был так хорош, как о нём говорят, то давно бы восседал на вершинах рейтингов. Но пока это не так. Поэтому не будем забегать вперёд и пока что постараемся ответить на основной вопрос: действительно ли Swift лучше Objective-C? Для этого рассмотрим основные плюсы и минусы.

Objective-C

Краткое описание. Язык, созданный в начале 80-х годов прошлого века, путём скрещивания С с популярным в то время Smalltalk. Изначально воспринимался, как простая надстройка, модифицирующая некоторые синтаксические конструкции, но после того, как за лицензирование взялась сначала компания NeXT, а потом на правах преемника и Apple, Objective-C стал одним из наиболее популярных языков для разработки приложений.

Плюсы:

  1. Динамическая типизация. В некоторых случаях, это действительно может стать ключевым преимуществом. Например, упрощает создание несложных программ.

  2. Документация и сообщества. Более 20 лет успешного применения языка поспособствовали появлению большого количества качественных ресурсов и книг. Сегодня любой, кто желает изучить Objective-C, без труда найдёт ответ на интересующий вопрос на просторах интернета.

  3. В сравнении с С++, да и многими другими языками того времени, Objective-C предоставляет разработчику куда больше гибкости.

  4. Относительная простота синтаксиса. Простота заключается в первую очередь в понимании алгоритмов и того, как работает исполняемая машина.

Минусы:

  1. Низкая читаемость кода, что затрудняет изучение языка новичкам.

  2. Динамическая типизация предполагает возможность появления (пропуска) ошибок даже во время компиляции. В частности, банальные опечатки могут серьёзно затянуть процесс.

  3. Ограниченная функциональность. Вполне логично, что язык, созданный в прошлом столетии, не может покрыть ту функциональность, что присуща современным конкурентам.

  4. Не самая высокая производительность, опять-таки вызванная динамической типизацией.

Swift

Краткое описание. В 2014 году специалисты Apple представили миру замену привычному Objective-C. Среди преследуемых целей были заявлены повышенная читаемость кода и устойчивость к ошибкам разработчика. Что получилось по факту, давайте посмотрим.

Плюсы:

  1. Для написания приложения требуется меньше кода, хотя бы просто потому, что здесь реализован упрощенный принцип работы с повторяющимися строками и заявлениями.

  2. Удобен для чтения. Стандартное достоинство любого современного языка.

  3. Больше возможностей по сравнению с Objective-C, в частности возможность управлять памятью.

  4. Полноценное взаимодействие с кодом, написанным на Objective-C.

  5. Повышенная безопасность. Это выражается и в обработке указателей, и в дотошности компилятора, и в том, что в саму компиляцию можно встроить опциональную переменную nil для обеспечения обратной связи.

Минусы:

  1. Из-за молодости языка и не переведённых на Swift кодов OS X и iOS требуется хотя бы минимальное знание Objective-C;

  2. Компилятор выдаёт излишние и просто сбивающие с толку ошибки, которые разработчику, пришедшему с других языков покажутся как минимум необычными.  

Взглянув на все плюсы и минусы, превосходство Swift сомнений не вызывает. Но что говорит статистика?

Обзор мнений и статистики

GitHub, периодически публикующий статистику по созданным исходникам кода, утверждает, что на сегодня Swift уже на самой вершине.

Покопавшись на портале Quora, ярые сторонники Objective-C смогут поднять себе настроение, прочитав сколько Swift уступает по производительности другим языкам.

Большинство профессиональных разработчиков, отвечая на вопрос “какой язык учить: Swift или Objective-C?”, уверенно отвечает — оба.

Что касается мнения крупных порталов, то здесь мнение единодушно: вряд ли вы найдете хоть одну статью, где победу в сравнении одерживает Objective-C. Исключительно Swift. Именно поэтому мы приглашаем вас на интенсив по основам Swift.

Итог

Некоторые преимущества есть у языка Objective-C, да и опытные разработчики склонны идеализировать его. Но от тотального яблочного господства Swift отделяет время и кропотливая работа создателей над недостатками. Ведь, довольно логично, что язык, явившийся миру всего пару лет назад должен пройти непростую стадию народной критики и доработки, прежде чем взойти на престол. А Objective-C постепенно уйдёт в историю, оставив о себе лишь добрую память.

Swift не нужен? / Хабр

Не перестаю задаваться вопросом — какие у Apple планы на Swift и Objective-C? Когда в 2014 году появился Swift, его создатель Крис Латтнер утверждал, что эти два языка смогут сосуществовать бесконечно долго. Из почтовой рассылки пользователям Xcode:

3 Июня 2014

McLaughlin, Michael P.

Кто-нибудь знает, действительно ли Apple собирается прекратить поддержку С и С++? Fortran уже не поддерживается, хотя осталось еще много кода на Fortran, и сравнительно нового, как в MultiNest.

Пожалуйста, скажите, что это не так. Не все считают, что «опытные пользователи» — это те, кто просто создает полнометражные мультики. Многие из них ученые и инженеры.

Здравствуйте, Michael,

Мы не строили планы на что-либо подобное. Swift — это просто новый вариант разработки под платформу. Мы не собираемся прекращать поддержку ни C, ни C++, ни Objective-C. Если вы разрабатываете на одном из этих языков, можете свободно продолжать его использовать.

— Крис.

Оригинальный текст письма

> On Jun 3, 2014, at 5:45 AM, McLaughlin, Michael P. <mpm…@mitre.org> wrote:

> Does anyone know, for real, if Apple intends to stop supporting C and C++?

> That’s what it sounded like. They already do not support Fortran even though

> there is a *lot* of Fortran code out there, even fairly new code like MultiNest.

>

> Please say it isn’t so. Not all of us consider “power users” to be just those

> who create feature-length cartoons. Many are scientists and engineers.

Hi Michael,

We have no plans to do anything like that. Swift is a new option for developing

on the platform. We have no plans to drop C, C++ or Objective-C. If you’re

happy with them, please feel free to keep using them.

-Chris

Дело в том, что в это никто не верит. Крис Латтнер уже давно покинул Apple, и если его утверждение окажется ложным, он не сможет принять критику от лица компании. В целом разработчики согласились на том, что Apple в конечном итоге откажется от Objective-C, и Swift станет единственным языком «первого класса» для разработки Cocoa-приложений. Слова «языком первого класса» имеют значение, потому что нет никаких оснований для прекращения поддержки компилятора для Objective-C или его удаления вообще. Компилятор поддерживает многие языки программирования, в том числе малоиспользуемые и старые. Так что утверждение Латтнера может быть формально истинным, но не в этом дело. Вопрос в выборе языка для разработки Cocoa-приложений под iOS и macOS.

Сообщество разработчиков, вероятно, право. Я согласен, что Objective-C и Swift не могут продолжать сосуществовать неопределенное время. Однако, я не так уверен, что будущее за Swift. Что, если это так? Этому варианту развития событий я бы и хотел посвятить эту статью. Во-первых, позвольте рассказать, почему Swift и Objective-C не могут мирно сосуществовать.

Новая надежда?

Ни Swift, ни Objective-C почти не используются за пределами платформ Apple. Это может поменяться в будущем, но на данный момент это факт. Так что если вы хотите разрабатывать приложения под платформы Apple, вам нужно изучить какой-либо из них, либо оба. «Какой именно язык изучать?» — довольно трудный вопрос для новичка. Если брать один язык, то стандартным советом будет Swift. Хотя я не согласен с ним, но признаю, что он стандартен. Умные головы предложат изучать оба языка. Но тут кроется загвоздка. Если нужно осваивать оба специфичных для платформы языка лишь для написания приложений, Apple-платформы теряют свою привлекательность для разработчиков. Swift понравился разработчикам из-за своей «современности» и «привычности», нежели Objective-C. Но если все равно нужно учить Objective-C, то в чем преимущество? Сторонние разработчики приняли Swift, гм … быстро (в оригинале тут получился каламбур, Swift = «быстро» — прим. пер.) — Apple сказали прыгнуть — они прыгнули. Как Аполлония в «Озеро Миннетонка». Swift стал очень популярным. Это вызвало огромный спрос на Swift-ресурсы. В почтовых рассылках, форумах, блогах, Stack Overflow, твиттере, да везде, — разработчики хотят знать о Swift и обсуждать его. Swift повлиял на техническую книгоиздательскую индустрию. Даже на рынок труда повлиял — многие компании намеренно, или из-за моды на язык, или просто из-за безграмотности, нанимают только Swift-разработчиков. Многие разработчики под платформы Apple не знают Objective-C. И многие Objective-С-разработчики берутся использовать исключительно Swift, причем до такой степени, что начинают забывать Objective-C и испытывают трудности, если приходится снова к нему возвращаться. Увлечение Swift, спрос на него среди разработчиков угрожают заглушить Objective-C. Эти два языка могут сосуществовать «официально» в сознании Apple, но могут ли они сосуществовать неофициально в чьем-либо еще? Могут ли приводиться двойные — на каждый язык — письма, блоги и вики-страницы? Что насчет опенсорсных проектов — Objective-C или Swift? И, если рынок труда движется почти исключительно к Swift, у разработчиков нет другого выхода, как идти в этом же направлении.

Империя наносит ответный удар

Судя по вышеуказанным аргументам, Objective-C обречен. Все больше разработчиков предпочитают Swift. Однако не все потеряно, потому что не разработчики управляют платформами Apple. Единственное место, где Swift еще не доминирует, это, как бы иронично ни звучало, сами Apple. Компания очень медленно осваивает Swift. К настоящему времени Apple внедрили удивительно мало Swift-кода. Хороший анализ этого можно найти в одном блоге. Было предложено несколько объяснений — многие могут называть это извинениями. Например, фреймворки Apple не могут использовать Swift, потому что он еще не достиг ABI-стабильности (или даже source-стабильности, если уж на то пошло). Каким бы ни было объяснение, факт остается фактом: внутренняя кодовая база Swift у Apple относительно крошечная, в то время как база Objective-C, скорее всего, самая большая в мире.

Если Apple придется отказаться от одного языка прямо сейчас, то от какого именно? Отказ от Swift будет чрезвычайно болезненным для сторонних разработчиков. С другой стороны, для самих Apple это пройдет почти незаметно — слишком мало Swift-кода придется конвертировать в Objective-C. Разумеется, Apple приложили немало усилий в Swift, особенно в отношении Xcode, однако, это невозвратные затраты. Apple не будут кидать денег на ветер. В Objective-C тоже было вложено немало, и эти затраты даже более невозвратны, чем у Swift. Значение имеет не цена, которую уже заплатили, а цена, которую придется заплатить в будущем. Apple ничего не имеют против невозвратных затрат. По слухам, они вложили огромную кучу денег в автомобильный проект, по которому еще ничего нет, и что он был по большей части отложен.

Apple могут переписать весь свой Objective-C-код на Swift, если захотят. Конечно, у них есть на это ресурсы. Объем ликвидных активов, которыми они владеют, просто ошеломителен, беспрецедентен в истории. Тем не менее, их нынешняя корпоративная культура предполагает, что они не могут или не будут выполнять это преобразование. За этим стоит несколько факторов. Во-первых, Apple перешли на годовой цикл выпуска для всех своих основных версий ОС. Действительно, по сообщениям, компания ударилась в Agile-философию разработки ПО. Такой подход оставляет слишком мало времени для полных переделок. И мы уже видели, как качество идет на спад, а функциональность теряется, когда Apple переписывает технологию или приложение с нуля.

Во-вторых, Apple гордятся тем, что нанимает «лучших» инженеров. Я знаю много специалистов как из Apple, так и нет, поэтому считаю это мифом. Но независимо от того, правда это или нет, это точка зрения компании, и, следовательно, вряд ли они смогут нанять огромное количество людей и бросить все ресурсы в перезапись Objective-C-кода.

В-третьих, опираясь на предыдущие моменты, скажу, что количество знающих Objective-C снижается. Даже если Apple захотят перевести кучу людей на эту задачу, где они их найдут? Если нужно переписать Objective-C в Swift, естественно, понадобятся специалисты, понимающие оба языка, без знания Objective-C вся затея превратится в катастрофу.

Внутренние исследования Apple также указывает, что если бы Софи пришлось выбирать (означает тяжелый выбор — прим.пер.) между двумя языками сегодня, то остался бы точно не Swift. Если вы сторонний разработчик, полностью окунувшийся в Swift, эта мысль, как минимум, должна вас напугать. И спросите себя, если сегодня маятник качнется в этом направлении, сколько времени должно пройти, и что должно произойти, чтобы он качнулся обратно? В какое время, в каком году для компании будет более болезненным отказаться от Swift, нежели от Objective-C?

Возможно, вы сейчас ворчите, мол, Apple не может так предать разработчиков, отказавшись от Swift. Как вообще руководителям Apple спится по ночам? Подозреваю, на матрасах, начиненных наличкой. Они не станут думать дважды. Они даже могут хвалить себя за смелость. Если вы посмотрите историю взаимоотношений Apple с разработчиками, то увидите целую цепочку отказов в поддержке, разочарований, страданий и несдержанных обещаний. Сборщик мусора в Objective-C, 64-битный Carbon, интерфейс Cocoa-Java, Yellow Box для Windows, Dylan. Нужно ли продолжать? Я мог бы. Евангелисты Apple скажут вам, что Swift — лучший язык программирования, а затем передумают и заявят, что они всегда были против Swift.

Приквелы

Когда Apple решили создать Swift, каков был их план? Я вижу три варианта.

  1. Они действительно намеревались поддерживать оба языка какое-то неопределенное время.
  2. Планировали в конце концов отказаться от Objective-C и перейти на Swift, во что и верят разработчики.
  3. У них не было конкретного плана, да и вообще не были уверены, что Swift даже выстрелит.

Первый вариант не подходит по вышеописанным причинам, так что его сразу можно отмести.

Если действующим был второй план, я бы очень хотел, чтобы Apple в открытую его выразили. Сообщение от Латтнера, как минимум, вводит в заблуждение. Если Swift — будущее, так почему бы не быть откровенными с разработчиками, не делиться с ними своими планами, чтобы те смогли подстроиться под них? Неопределенность — худшее, что может быть в этом отношении. Мы сможем согласиться, что Swift — наше будущее, если у нас не останется выбора. Но если Swift — выбор Apple, и они кормят нас иллюзиями, что выбор все еще есть, тогда некоторые из разработчиков могут сделать неправильный выбор, что губительно для всех.

Я считаю, что верен третий вариант. Я знаю, многие люди думают, что Apple работают в соответствии с каким-то грандиозным, секретным, мегабольшим планом. Есть ли у Apple долгосрочные планы? Несомненно. Являются ли эти планы конкретными? Сомневаюсь. В технической сфере вы можете делать долгосрочные планы, но не рассчитывайте, что сможете им придерживаться. Технологии меняются… быстро. Вам надо быть гибкими (не как Agile, а просто гибкими). Вы должны уметь реагировать на то, что делают ваши конкуренты. Например, уход Леттнера — было ли это в планах Apple? Планы меняются. Они должны меняться. Сторонние разработчики сразу же набросились на Swift, но Apple также должны были учесть возможность того, что он пройдет незаметно для них. Надеясь на лучшее, планируй худшее.

Изгой-один

По общему мнению, проект «Swift» был секретным даже внутри Apple. О нем знали лишь несколько избранных. Когда о нем объявили в открытую, для большинства инженеров Apple это стало такой же неожиданностью, как и для разработчиков. Сотрудники Apple оказались не готовы для этого. И это представляет собой самую большую проблему для Swift: внутренние конфликты между командами разработки в Apple. Команда-за-Swift с поддержкой в лице руководства преподносят Swift как будущее разработки приложений Apple. Но Команда-за-Swift не может просто так отмести настоящее и поставить на его место будущее как установленный факт. Настоящее для Apple — Objective-C. Много Objective-C. Десятилетия Objective-C, накопившиеся еще до покупки NeXT. Вся кодовая база Objective-C не может просто так исчезнуть, как по мановению волшебной палочки. Вы представляете Swift группе команд Apple, которые ограничены как во времени, так и в ресурсах, все, что они сделают — пошлют вас к черту. Им может понравиться сама идея, но WWDC близко и нужно выполнить кучу работы. Может быть, через год… Или через два.

Как Apple может согласовать эти конкурирующие интересы? Они хотят закрепить будущее за Swift, но также есть тонна Objective-C-кода, и они хотят продолжить свою гибкую разработку ПО, при этом нанимая исключительно лучших инженеров. Да еще и поддерживать качество ПО. (Надеюсь, можно предположить, что там все-таки заботятся о качестве.) Чем-то придется пожертвовать. Между тем, сторонние разработчики будут предъявлять бОльшие требования к ресурсам Swift. Описания API, вероятно, в значительной степени автоматизированы, так что двойной стек не будет большой проблемой, но разработчикам на Swift потребуется документация и примеры кода. Если официальная позиция Apple состоит в поддержке обоих языков, они пишут двойную документацию и двойные примеры кода? И как много усилий они вкладывают в обновление старой Objective-C-документации?

Какова реакция сообщества на эту проблему? Люди, считающие, что Apple откажется от Objective-C, — как вы думаете, как они с этим справятся? Некоторые предположат, что Apple откажутся от внешнего использования Objective-C, но продолжат использовать его внутри компании. Однако, я думаю, что эти люди недооценивают проблему. Учитывая объем кодовой базы Objective-C и ограничения, с которыми Apple работают, переход на Swift действительно затянется. По-вашему, как долго компания будет поддерживать все инструменты для Objective-C? Если ваш ответ не 5 лет, не 10 лет и даже не более 10 лет, я думаю, вы не представляете объема всей задачи. Для меня кажется крайне маловероятным, что Apple будет выделять отдельные ресурсы для разработки и поддержки внутренней версии Xcode, внутренних Objective-C API, внутренней Objective-C-документации (всем нужна документация) и т. д. И еще раз, если бы компания официально отказалась от Objective-C, количество Objective-C-разработчиков падало бы еще более стремительными темпами, чем сейчас, так что где вообще Apple собирается найти людей для поддержки кодовой базы в будущем?

Эпизод C

Позвольте опровергнуть возможные контраргументы к вышеуказанным мной. Контраргумент состоит в том, что Apple и так тянут двойной стек технологий: Objective-C и C. Foundation и Core Foundation. Поэтому добавление еще одного языка не является чем-то новым и неизведанным. Это возражение на первый взгляд кажется убедительным, но тут есть брешь. Да, Objective-C и C являются двумя разными языками, но провести аналогию со Swift нельзя, потому что Objective-C — это, по сути, надстройка над C. Если вы изучаете Objective-C, и изучаете хорошо, значит вы знаете и C тоже. Не имеет значения, что многие берутся сначала за C, а потом за Objective-C. На самом деле, я шел именно по этому пути, и советовал бы следовать ему и другим. Но изучение C и затем Objective-C — не то же самое, что учить два языка программирования. Фактически, это попросту двухэтапное изучение Objective-C. Все, что вы узнали о C, применимо и к Objective-C. Это просто работает, так сказать. Но Swift это не касается. Конечно, есть некоторые пересечения, потому что Swift был разработан людьми, оперирующими Objective-C, но ни в коем случае ни один из них не является надстройкой над другим. Swift и Objective-C несовместимы гораздо хуже, чем, скажем, C++ и C, которые весьма близки, но не совсем совместимы.

Кроме того, C не является языком разработки приложений под iOS и macOS. Можете ли вы создать приложение на чистом C? Возможно, но, конечно, не легко. API для разработки на C был не Cocoa, а, скорее, Carbon, а от Carbon Apple в значительной степени отказались. Существует несколько поддерживаемых API для C в Apple-платформах, но все же C не так близок к разработке iOS- и macOS-приложений, как Objective-C и Swift.

Какая-то там месть

Это лишь мои подозрения, но мне кажется, что Apple не ожидали, что Swift так быстро станет популярным. Вся эта стратегия имела бы больший смысл, если бы Swift медленно развивался в течение долгих лет. Двойной стек выгоден, если разработчики распределены на два лагеря примерно равномерно. У Apple и сторонних разработчиков было бы достаточно времени, чтобы переписать существующий код с Objective-C на Swift. Swift может быть нашим будущим, может быть единственным языком для разработки, но это отдаленное будущее. Может оказаться ошибкой в планировании или игрой воображения, что Swift может внезапно подавить Objective-C в мышлении разработчиков. И теперь Apple столкнулась с трудным выбором. Как они справляются с неожиданной популярностью Swift за пределами компании, когда внутри нее к нему еще не готовы?

Я подозреваю, что Apple отступятся от Swift. Как я думаю, отставка Леттнера делает эту возможность еще более вероятной. Многие разработчики положили все свои ресурсы на Swift. Это могло казаться неплохим вложением в то время, и возможно, оно окупится. Вероятно, это окупится. Что, если нет? Вдруг произойдет смена управления, или просто изменятся настроения внутри управления? Что если Apple внезапно решит, что их внутренние ограничения труднее преодолеть, чем они ожидали и смена языка невыгодна? Можете ли вы исключить эту возможность? Боюсь, многие не готовы к настолько жестокому миру. Если это произойдет, будет много слез и криков. Но не среди разработчиков Objective-C, которые будут смеяться и веселиться, как будто на дворе 1999. В крайнем случае, 2001.

Swift vs Objective-C vs Си

Разработчик из Сан-Франциско, Джесси Сквайрс (Jesse Squires), опубликовал в своем блоге сравнительные результаты тестирования приложений, написанных на трех разных языках программирования: Swift, Objective-C и Си.

Напомним, что первый из них был анонсирован разработавшей его Apple в первый день WWDC 2014, и вместе с графическим интерфейсом Metal (который согласно компании демонстрирует 10-кратный прирост графической производительности по сравнению с традиционным OpenGL) стал главным событием этой конференции (хотя большинство обычных пользователей яблочной продукции возможно больше заинтересовала презентация OS X Yosemite и iOS 8). Swift пришел на смену Objective-C — языка программирования, ставшего объектно-ориентированным расширением процедурного языка Си и используемого разработчиками платформ Apple аж с 1983 года. Таким образом, выход Swift ознаменовал завершение 21-летней эпохи языка Objective-C. Неудивительно, что на новичка (имя которого в переводе на русский звучит как «быстрый») возлагаются большие надежды. И судя по результатам проведенных Джесси Сквайрсом испытаний, эти надежды всецело оправдываются.

Быстродействие языков тестировалось путем замера скорости сортировок, алгоритмы которых были написаны на всех трех языках. Главный интерес представляют результаты по Swift и Objective-C, классический Си использовался как своего рода критерий. Скорость выполнения написанных на нем программ благодаря низкому, приближающемуся к машинному, уровню абстракции, является очень высокой по сравнению с языками высокого уровня (к категории которых относятся Swift и Objective-C). Те в меньшей степени учитывают особенности компьютерного железа, удобнее в написании прикладных программ, но по этой же причине медленнее работают.

Результаты испытаний варьируют в зависимости от заданных уровней оптимизации при компиляции исходного кода, а также бета-версий Xcode 6 — интегрированной среды разработки под операционные системы OS X Yosemite и iOS 8. В ранних первых тестах, начиная со 2-ой бета-версии Xcode 6, при отключенной или установленной по умолчанию стандартной оптимизации, Swift вчистую проиграл своему предшественнику, обойдя его только при самом высоком (т.е. более быстродействующем, но и в большей степени подверженном ошибкам) уровне оптимизации кода. В следующих тестах, с очередными бета-версиями Xcode 6 (5-ой и 6-ой), быстродействие Swift значительно возросло: по-прежнему значительно уступая Objective-C при отключенной оптимизации, Swift превзошел его на стандартной оптимизации от 6 до 18 раз, а на высокой — от 7 до 35 раз, в зависимости от типа сортировки. Согласитесь, это очень  впечатляющий прирост быстродействия, демонстрирующий явное превосходство Swift по сравнению с Objective-C.

Что касается сравнения с Си (эти результаты Джесси Сквайрс опубликовал как раз сегодня), то и здесь новый язык программирования не упал лицом в грязь: на среднем и максимальном уровне оптимизации Swift уступил Си самое большее в 4.5-раза, ухитрившись превзойти его в 1.5-2 раза в одном из алгоритмов сортировки.

Подчеркиваем, что речь идет о бета-версии, выпущенной полтора месяца спустя после первого релиза. Не исключено, в последующих версиях производительность приложений, написанных на Swift и скомпилированных в Xcode 6, окажется еще выше.

Язык программирования Swift. Русская версия / Блог компании Apphud / Хабр

Привет, Хабр! 2 июня все мы воочию могли наблюдать, как компания Apple начала творить революцию в стане Objective-C разработчиков, представив миру свой новый язык программирования – Swift. Вместе с этим, она выложила в открытый доступ небольшую документацию по языку, которую мы решили перевести, если на то будет спрос. Предлагаем вашему вниманию перевод первой главы. Если тема будет интересна, то мы продолжим публиковать перевод каждую неделю.

Оглавление

Добро пожаловать в Swift

    О Swift

    Введение в Swift

Language guide

    The Basics

    Basic Operators

    String and Characters

    Collection Types

    Control Flow

    Functions

    Closures

    Enumerations

    Classes and Structures

    Properties

    Methods

    Subscripts

    Inheritance

    Initialization

    Deinitialization

    Automatic Reference Counting

    Optional Chaining

    Type Casting

    Nested Types

    Extensions

    Protocols

    Generics

    Advanced Operators

Language Reference

    About the Language Reference

    Lexical Structure

    Types

    Expressions

    Statements

    Declarations

    Attributes

    Patterns

    Generic Parameters and Arguments

    Summary of the Grammar

    Trademarks

Добро пожаловать в Swift

О языке Swift

Swift – это новый язык программирования для разработки iOS и OS X приложений, который сочетает в себе все лучшее от C и Objective-C, но лишен ограничений, накладываемых в угоду совместимости с C. В Swift используются паттерны безопасного программирования и добавлены современные функции, превращающие создание приложения в простой, более гибкий и увлекательный процесс. Swift, созданый нами с чистого листа, – это возможность заново представить себе, как разрабатываются приложения.

Swift разрабатывался нами несколько лет. Основой нового языка программирования послужили существующие компилятор, отладчик и фреймворки. Мы упростили процесс управления памятью с помощью механизма автоматического подсчета ссылок – Automatic Reference Counting (ARC). Наши фреймворки также подверглись серьезной модернизации. Objective-C начал поддерживать блоки, литералы и модули – все это создало благоприятные условия для внедрения современных технологий. Именно эта подготовительная работа послужила фундаментом для нового языка программирования, который будет применяться для разработки будущих программных продуктов для Apple.

Разработчикам Objective-C Swift покажется знакомым. Он сочетает в себе читабельность именованных параметров и мощь динамической объектной модели Objective-C. Он открывает доступ к уже существующим фреймворкам Cocoa и совместим с кодом, написанным на Objective-C. Построенный на этой общей основе язык предлагает множество новых возможностей и унифицирует процедурные и объектно-ориентированные аспекты языка программирования.

Swift не отпугнет и начинающих программистов. Это первый мощный язык программирования, такой же понятный и увлекательный, как скриптовый язык. Он поддерживает так называемые playground-ы, которые позволяют программистам экспериментировать с кодом, видя результат в режиме реального времени без необходимости компилировать и запускать приложение.

Swift вобрал в себя все лучшее от современных языков и разработан с учетом обширного опыта компании Apple. Наш компилятор – синоним производительности, наш язык оптимизирован для разработки без оглядки на компромиссы. Он спроектирован таким образом, чтобы вы смогли легко разработать и ваше первое приложение «hello, world!», и даже целую операционную систему. Все это делает Swift важным инструментом для разработчиков и для самой компании Apple.

Swift – это новый фантастический способ создавать приложения для iOS и OS X, и мы продолжим развивать его, добавляя новый функционал и представляя новые возможности. Наша цель – амбициозна. И мы с нетерпением ждем, чтобы увидеть, что вы сумеете создать при помощи него.

Введение в Swift

По давней традиции первая программа на новом языке должна выводить на экран слова “Hello, world”. С помощью Swift это делается так:

println("Hello, world")

Если вы когда-нибудь разрабатывали на C или Objective-C этот синтаксис должен казаться вам до боли знакомым – в Swift эта строчка кода является законченной программой. Вам больше не нужно импортировать отдельные библиотеки для обеспечения базового функционала вроде ввода/вывода в консоль или работы со строками. Код, написанный в глобальной области видимости, является точкой входа в программу, таким образом функция main больше не нужна. Также обратите внимание на отсутствие точки с запятой в конце каждой строки.

Это введение содержит достаточно информации, чтобы начать писать код на Swift. Не переживайте, если вам будет что-то непонятно – мы все детально объясним в последующих главах.

Замечание

Для лучшего понимания материала мы рекомендуем использовать режим playground в Xcode. Playground позволяет вам видеть результат сразу в процессе редактирования кода без необходимости компилировать и запускать приложение.

Простые типы данных

Используйте let для создания константы и var для создания переменной. Тип константы указывать не нужно, вы можете присвоить ей значение лишь единожды.

var myVariable = 42
myVariable = 50
let myConstant = 42

Типы константы и переменной должны совпадать с типами присваиваемых им соответствующих значений. Однако это не означает, что вы должны напрямую указывать их тип. Компилятор автоматически определит тип константы и переменной при присваивании им значения. Так, в приведенном примере компилятор определит, что myVariable имеет целочисленный тип.

Если же инициализатор отсутствует или не предоставляет достаточной информации, вы можете указать тип самостоятельно после переменной, разделив название и тип двоеточием:

let implicitInteger = 70
let inplicitDouble = 70.0
let inplicitDouble: Double = 70

Давайте поэкспериментируем

Создайте константу с типом Float и проинициализируйте ее числом 4.

Значения никогда не конвертируются в другой тип неявно. Если вам необходимо конвертировать значение в другой тип, делайте это явно:

let label = "The width is "
let width = 94
let widthLabel = label + String(width)

Давайте поэкспериментируем

Попробуйте удалить явное преобразование к типу String в последней строке. Какую ошибку вы получите?

Имеется более простой способ включения значений в строки: для этого заключите выражение в скобки и поставьте перед ними обратный слэш (\). Пример:

let apples = 3
let oranges = 5
let appleSummary = "I have \(apples) apples."
let fruitSummary = "I have \(apples + oranges) pieces of fruit."

Давайте поэкспериментируем

Попробуйте использовать конструкцию \() и выведите на экран строку, включающую результат суммы двух целочисленных переменных и чье-нибудь имя.

При работе с массивами и ассоциативными массивами (словарями, dictionary) используются квадратные скобки ([]):

var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"
 
var occupations = [
    "Malcolm": "Captain",
    "Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"

Чтобы создать пустой массив или dictionary, используйте следующий синтаксис:

let emptyArray = String[]()
let emptyDictionary = Dictionary<String, Float>()

Для создания пустых массивов и словарей используйте [] и [:] соответственно, – например, когда вы присваиваете новое значение переменной или передаете аргумент в функцию.

shoppingList = []   // Went shopping and bought everything.
Условия и циклы

Для создания условий используются операторы if и switch, для создания циклов – for-in, for, while и do-while. При этом выделять круглыми скобками условия и инициализирующие выражения необязательно, тогда как фигурные скобки обязательны.

let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {
    if score > 50 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
teamScore

Условие внутри оператора if должно быть логическим, это в частности означает, что выражение if score {…} является ошибочным, поскольку здесь нет явного сравнения (например, с нулем).

Условный оператор if можно использовать совместно с let и var для работы с константами и переменными, которые могут иметь значение nil. Такие константы и переменные называются опциональными (то есть они могут либо принимать какое-либо значение, либо быть равны nil). Чтобы создать опциональную переменную или константу добавьте знак вопроса (?) после указания типа.

 var optionalString: String? = "Hello"
optionalString == nil
 
var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
    greeting = "Hello, \(name)"
}

Давайте поэкспериментируем

Измените optionalName на nil. Что вы видите на экране? Добавьте блок else для обработки случая, когда optionalName равен nil.

Если опциональное значение равно nil, условие будет ложным и код в фигурных скобках после if выполнен не будет. В противном случае переменной greeting будет присвоено новое значение.

Оператор множественного выбора switch поддерживает внутри себя множество других операторов сравнения и не ограничен лишь простыми сравнениями:

let vegetable = "red pepper"
switch vegetable {
case "celery":
    let vegetableComment = "Add some raisins and make ants on a log."
case "cucumber", "watercress":
    let vegetableComment = "That would make a good tea sandwich."
case let x where x.hasSuffix("pepper"):
    let vegetableComment = "Is it a spicy \(x)?"
default:
    let vegetableComment = "Everything tastes good in soup."
}

Давайте поэкспериментируем

Попробуйте удалить условие по умолчанию. Какую ошибку вы получите?

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

Для перебирания элементов ассоциативного массива используйте оператор for-in совместно с указанием пары имен для каждой пары ключ-значение.

let interestingNumbers = [
    "Prime": [2, 3, 5, 7, 11, 13],
    "Fibonacci": [1, 1, 2, 3, 5, 8],
    "Square": [1, 4, 9, 16, 25],
]
var largest = 0
for (kind, numbers) in interestingNumbers {
    for number in numbers {
        if number > largest {
            largest = number
        }
    }
}
largest

Давайте поэкспериментируем

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

Оператор цикла while позволяет выполнять блок кода внутри него до тех пор, пока условие не станет ложным. Условие также может быть указано после блока, который в таком случае будет выполнен по крайней мере один раз.

var n = 2
while n < 100 {
    n = n * 2
}
n
 
var m = 2
do {
    m = m * 2
} while m < 100
m

Оператор for можно использовать для перебора последовательности чисел с помощью двух точек (..) или с помощью инициализатора, условия и инкремента. Посмотрите, эти два цикла делают одно и то же:

var firstForLoop = 0
for i in 0..3 {
    firstForLoop += i
}
firstForLoop
 
var secondForLoop = 0
for var i = 0; i < 3; ++i {
    secondForLoop += 1
}
secondForLoop

При создании цикла используйте две точки (..), если не хотите включать большее значение в диапазон, и три точки (), чтобы включить как меньшее, так и большее значения.

Функции и замыкания.

Для объявления функций используйте ключевое слово func. Вызов функции производится через указание ее имени и списка аргументов в круглых скобках. Возвращаемый тип следует отделить от перечня формальных аргументов с помощью ->.

func greet(name: String, day: String) -> String {
    return "Hello \(name), today is \(day)."
}
greet("Bob", "Tuesday")

Давайте поэкспериментируем

Удалите параметр day. Вместо него добавьте переменную, обозначающую наименование подаваемого на обед блюда.

Если функция возвращает множество значений, следует использовать кортеж:

func getGasPrices() -> (Double, Double, Double) {
    return (3.59, 3.69, 3.79)
}
getGasPrices()

Функции также могут иметь неопределенное число аргументов:

func sumOf(numbers: Int...) -> Int {
    var sum = 0
    for number in numbers {
        sum += number
    }
    return sum
}
sumOf()
sumOf(42, 597, 12)

Давайте поэкспериментируем

Напишите функцию, позволяющую находить среднее арифметическое произвольного числа своих аргументов.

Функции могут вкладываться друг в друга. Вложенная функция может обращаться к переменным, объявленным во внешней функции. Используйте вложенные функции, чтобы привести в порядок код сложной или большой функции.

func returnFifteen() -> Int {
    var y = 10
    func add() {
        y += 5
    }
    add()
    return y
}
returnFifteen()

Функции являются объектами первого класса (first-class type), иными словами, функция в качестве свого результата может возвращать другую функцию.

func makeIncrementer() -> (Int -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)

Функция также может принимать другую функцию в качестве одного из аргументов.

func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool {
    for item in list {
        if condition(item) {
            return true
        }
    }
    return false
}
func lessThanTen(number: Int) -> Bool {
    return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(numbers, lessThanTen)

Функции являются частным случаем замыканий. Вы можете создать замыкание, не указывая его имени и окружив тело замыкания фигурными скобками ({}). Для отделения аргументов и типа возвращаемого значения от тела замыкания используйте оператор in.

numbers.map({
    (number: Int) -> Int in
    let result = 3 * number
    return result
    })

Давайте поэкспериментируем

Перепишите замыкание таким образом, чтобы оно возвращало ноль для всех лишних чисел.

Существует несколько техник, позволяющих делать замыкания более лаконичными. Если тип замыкания априори известен (например, это callback делегата), можно опустить указание типа его параметров и/или типа возвращаемого значения. Замыкания, состоящие из единственного выражения, неявно возвращают результат этого выражения.

numbers.map({ number in 3 * number })

В замыкании вместо указания имени переменной, вы можете использовать ее порядковый номер – это особенно полезно при написании коротких замыканий. Замыкание, являющееся последним аргументом функции, может быть передано в нее сразу после круглых скобок с перечнем остальных параметров.

sort([1, 5, 3, 12, 2]) { $0 > $1 }
Объекты и классы

Для создания класса используется зарезервированное слово class. Члены класса объявляются точно так же, как и обычные константы и переменные. Более того, методы класса объявляются как обычные функции.

class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

Давайте поэкспериментируем

Добавьте константу-член класса и метод класса, принимающую ее в качестве своего аргумента.

Чтобы создать экземпляр (объект) класса, достаточно добавить круглые скобки после названия класса. Доступ к методам и членам класса осуществляется через точку.

var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()

В этом примере мы упустили одну важную деталь – конструктор класса, метод init.

class NamedShape {
    var numberOfSides: Int = 0
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

Обратите внимание, как член класса name при помощи self отделен от аргумента конструктора name. Аргументы передаются в конструктор обычным образом, как и в любой другой метод класса. Обратите внимание на то, что каждый член класса должен быть проинициализирован – либо при объявлении (как, например, numberOfSides), либо в конструкторе (как name).

Деструктор класса – метод deinit, который можно переписать в случае необходимости.

Чтобы наследовать класс от уже существующего класса, после указания имени дочернего класса следует поставить двоеточие и указать название родительского. В Swift нет никаких ограничений по обязательному наследованию какого-либо стандартного класса.

Переопределенные дочерним классом методы должны быть помечены ключевым словом override – переопределение методов без override приведет к ошибке. Компилятор также выявляет методы, маркированные override, но не переопределяющие какие-либо методы своего родительского класса.

class Square: NamedShape {
    var sideLength: Double
    
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 4
    }
    
    func area() ->  Double {
        return sideLength * sideLength
    }
    
    override func simpleDescription() -> String {
        return "A square with sides of length \(sideLength)."
    }
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()

Давайте поэкспериментируем

Создайте класс Circle и наследуйте его от класса NamedShape. Конструктор класса Circle принимает два аргумента – радиус и название. Переопределите методы area и describe этого класса.

Члены класса могут также иметь собственные getter и setter.

class EquilateralTriangle: NamedShape {
    var sideLength: Double = 0.0
    
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 3
    }
    
    var perimeter: Double {
    get {
        return 3.0 * sideLength
    }
    set {
        sideLength = newValue / 3.0
    }
    }
    
    override func simpleDescription() -> String {
        return "An equilateral triagle with sides of length \(sideLength)."
    }
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength

В setter-е переменной perimeter новое присваиваемое значение неявно называется newValue. Вы можете изменить название этой переменной, указав его в скобках сразу после set.

Обратите внимание на структуру конструктора класса EquilateralTriangle. Этот метод включает в себя три последовательных шага:

  1. инициализация членов дочернего класса;
  2. вызов конструктора родительского класса;
  3. изменение значений членов родительского класса.

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

class TriangleAndSquare {
    var triangle: EquilateralTriangle {
    willSet {
        square.sideLength = newValue.sideLength
    }
    }
    var square: Square {
    willSet {
        triangle.sideLength = newValue.sideLength
    }
    }
    init(size: Double, name: String) {
        square = Square(sideLength: size, name: name)
        triangle = EquilateralTriangle(sideLength: size, name: name)
    }
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
triangleAndSquare.square.sideLength
triangleAndSquare.triangle.sideLength
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
triangleAndSquare.triangle.sideLength

У методов классов имеется одно важное отличие от функций. Названия аргументов функции используются только в пределах этой функции, тогда как в методе класса параметры также используются при вызове этого метода (кроме первого параметра). По умолчанию метод класса имеет одинаковые названия параметров как при вызове, так и внутри себя. Однако вы можете указать другое название (в примере ниже – times), которое будет использовано только внутри этого метода. При этом для вызова этого метода необходимо использовать первое название (numberOfTimes).

class Counter {
    var count: Int = 0
    func incrementBy(amount: Int, numberOfTimes times: Int) {
        count += amount * times
    }
}
var counter = Counter()
counter.incrementBy(2, numberOfTimes: 7)

При работе с опциональными значениями добавьте знак вопроса (?) перед методами, членами класса и т.д. Если значение перед знаком вопроса равно nil, все, что следует после (?) игнорируется и значение всего выражения равно nil. В противном случае выражение вычисляется обычным образом. В обоих случаях результатом всего выражения будет опциональное значение.

let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength
Перечисления и Структуры

Для создания перечислений используется ключевое слово enum. Отметим, что перечисления также могут иметь в своем составе методы.

enum Rank: Int {
    case Ace = 1
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King
    func simpleDescription() -> String {
        switch self {
        case .Ace:
            return "ace"
        case .Jack:
            return "jack"
        case .Queen:
            return "queen"
        case .King:
            return "king"
        default:
            return String(self.toRaw())
        }
    }
}
let ace = Rank.Ace
let aceRawValue = ace.toRaw()

Давайте поэкспериментируем

Напишите функцию, которая сравнивает 2 перечисления типа Rank по их значениям.

В вышеприведенном примере элементы перечисления первоначально имеют целочисленный тип, и вам достаточно указать значение только первого элемента – значения остальных элементов будут определены в соответствии с порядком их следования. В качестве исходного типа (raw value) значений элементов вы также можете выбрать строковый или вещественные типы.

Для преобразования исходного типа значения в тип перечисления используйте функции toRaw и fromRaw.

if let convertedRank = Rank.fromRaw(3) {
    let threeDescription = convertedRank.simpleDescription()
}

Отметим, что значения элементов перечисления являются фактическими, а не просто иной записью своих исходных значений. Вообще говоря, вы можете и не указывать их исходные значения.

enum Suit {
    case Spades, Hearts, Diamonds, Clubs
    func simpleDescription() -> String {
        switch self {
        case .Spades:
            return "spades"
        case .Hearts:
            return "hearts"
        case .Diamonds:
            return "diamonds"
        case .Clubs:
            return "clubs"
        }
    }
}
let hearts = Suit.Hearts
let heartsDescription = hearts.simpleDescription()

Давайте поэкспериментируем

Добавьте метод Color, возвращающий строку “black” для Spades и Clubs и “red” для Hearts и Diamonds.

Обратите внимание на то, как осуществляется доступ к члену Hearts перечисления Suit. При присваивании значения константе hearts используется полное имя Suit.Hearts, поскольку мы явно не указываем тип этой константы. А в switch мы используем сокращенную форму .Hearts, поскольку тип значения self априори известен. Вы можете использовать сокращенную форму повсеместно, если тип переменной явно указан.

Для создания структур используется ключевое слово struct. Структуры имеют множество схожих черт с классами, включая методы и конструкторы. Одним из наиболее существенных отличий структур от классов является то, что экземпляры структур, в отличие от экземпляров классов, передаются в функции по значению (то есть предварительно создается их локальная копия), тогда как экземпляры классов передаются по ссылке.

struct Card {
    var rank: Rank
    var suit: Suit
    func simpleDescription() -> String {
        return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
    }
}
let threeOfSpades = Card(rank: .Three, suit: .Spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

Давайте поэкспериментируем

Добавьте в структуру Card метод, который создает полную колоду карт.

Экземпляр члена перечисления может иметь собственные значения и они могут быть разными. Вы присваиваете эти значения при создании экземпляра перечисления (константа success в примере). Связанные и исходные значения это разные вещи: исходное значение члена перечисления всегда постоянно для всех экземпляров перечисления и указывается при его объявлении.

Рассмотрим пример получения с сервера времени восхода и заката Солнца. Сервер отправляет в ответ либо соответствующую информацию, либо сообщение об ошибке.

enum ServerResponse {
    case Result(String, String)
    case Error(String)
}
 
let success = ServerResponse.Result("6:00 am", "8:09 pm")
let failure = ServerResponse.Error("Out of cheese.")
 
switch success {
case let .Result(sunrise, sunset):
    let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)."
case let .Error(error):
    let serverResponse = "Failure...  \(error)"
}

Давайте поэкспериментируем

Добавьте третий вариант в оператор множественного выбора switch

Обратите внимание, каким образом из объекта ServerResponse “вытаскиваются” время восхода и заката.

Протоколы и Расширения.

Для объявления протокола используйте ключевое слово protocol.

protocol ExampleProtocol {
    var simpleDescription: String { get }
    mutating func adjust()
}

Протоколы могут поддерживаться классами, перечислениями и структурами.

class SimpleClass: ExampleProtocol {
    var simpleDescription: String = "A very simple class."
    var anotherProperty: Int = 69105
    func adjust() {
        simpleDescription += "  Now 100% adjusted."
    }
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription
 
struct SimpleStructure: ExampleProtocol {
    var simpleDescription: String = "A simple structure"
    mutating func adjust() {
        simpleDescription += " (adjusted)"
    }
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription

Давайте поэкспериментируем

Создайте перечисление, которое будет реализовывать этот протокол.

Обратите внимание на ключевое слово mutating в определении структуры SimpleStructure, которое информирует компилятор о том, что соответствующий метод подвергает структуру изменениям. В противовес этому методы класса SimpleClass не нужно маркировать как mutating, поскольку методы класса всегда могут беспрепятственно его изменять.

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

extension Int: ExampleProtocol {
    var simpleDescription: String {
    return "The number \(self)"
    }
    mutating func adjust() {
        self += 42
    }
}
7.simpleDescription

Давайте поэкспериментируем

Создайте расширение типа Double с переменной-членом absoluteValue.

Вы можете использовать название протокола как и любой другой тип – например, чтобы создать массив объектов разного типа, но реализующих общий протокол. Заметьте, что при работе с объектами такого типа методы, объявленные вне протокола, будут недоступны.

let protocolValue: ExampleProtocol = a
protocolValue.simpleDescription
// protocolValue.anotherProperty  // Uncomment to see the error

Несмотря на то, что во время выполнения программы переменная protocolValue имеет тип SimpleClass, компилятор считает, что ее тип – ExampleProtocol. Это означает, что вы не сможете случайно получить доступ к методам или членам класса, которые реализуются вне протокола ExampleProtocol.

Обобщенные типы (generics)

Для создания обобщенного типа, заключите имя в угловые скобки (<>).

func repeat<ItemType>(item: ItemType, times: Int) -> ItemType[] {
    var result = ItemType[]()
    for i in 0..times {
        result += item
    }
    return result
}
repeat("knock", 4)

Создавайте обобщенные функции, классы, перечисления и структуры.

// Reimplement the Swift standard library's optional type
enum OptionalValue<T> {
    case None
    case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)

Если вы хотите задать обобщенные типу определенные требования, такие, как, например, реализация протокола или требование быть наследованным от определенного класса, используйте where.

func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Bool {
    for lhsItem in lhs {
        for rhsItem in rhs {
            if lhsItem == rhsItem {
                return true
            }
        }
    }
    return false
}
anyCommonElements([1, 2, 3], [3])

Давайте поэкспериментируем

Измените функцию anyCommonElements таким образом, чтобы она возвращала массив общих элементов.

В простых случаях вы можете опустить where и написать имя протокола или класса после двоеточия. Выражение <T: Equatable> эквивалентно выражению <T where T: Equatable>.

Хотите внедрить подписки в iOS-приложение за 10 минут? Интегрируйте Apphud и:

— оформляйте покупки с помощью лишь одного метода;

— автоматически отслеживайте состояние подписки каждого пользователя;

— легко интегрируйте Subscription Offers;

— отправляйте события о подписках в Amplitude, Mixpanel, Slack и Telegram с учетом локальной валюты пользователя;

— уменьшайте Churn rate в приложениях и возвращайте отписавшихся пользователей.

Swift vs. Objective-C: что выбрать для разработки под iOS

Когда дело доходит до создания любого программного решения, одна из ключевых задач — выбрать подходящий язык программирования. Для приложений iOS наиболее распространенными вариантами выбора являются Swift или Objective-C.

В этой статье проводится сравнение Swift и Objective-C, чтобы помочь вам понять, какой язык лучше всего подходит для вашего проекта.

Objective-C против Swift: история и характеристики

Прежде чем мы сможем сравнить эти языки программирования, давайте узнаем об их происхождении и основных функциях.

Objective-C

Этот язык на основе компилятора впервые появился в 1980-х годах и до сих пор используется программистами во всем мире. Objective-C был приобретен Apple и стал фундаментальной основой для разработки приложений для iOS и OS X. Таким образом, минимальное знание этого языка программирования является обязательным для тех, кто хочет построить карьеру в качестве разработчика Apple.

Модель Objective-C основана на отправке сообщений объектам, поэтому она называется объектно-ориентированным языком.Целью Брэндона Кокса, создателя Objective-C, было решить проблему повторного использования кода, чтобы снизить требования к системным ресурсам и улучшить качество и производительность кода.

Созданный на основе парадигм Smalltalk и одновременно являющийся расширением языка C, Objective-C унаследовал сложный синтаксис. Он также использует динамическую типизацию и многочисленные правила кодирования, которые необходимо соблюдать (одно из них — использование заглавных букв, известное как верблюжий регистр).

Вы должны знать, что порог входа в среду программирования с этим языком довольно высок.Для новичков принципы ООП и подробный синтаксис обычно являются крепким орешком. Тем не менее, Objective-C не составит труда изучить для тех, кто знаком с языками программирования на основе C, например C # или Java, а также расширенные объектно-ориентированные языки, например Python или Ruby. Также доступно достаточное количество документации и руководств для освоения Objective-C.

Obj-C используется для кодирования приложений для любого устройства Apple, будь то iPhone, Mac, Apple Watch или даже CarPlay.Итак, разработчики Objective-C будут пользоваться большим спросом еще как минимум лет пять или больше.

Swift

Несмотря на то, что Objective-C является зрелым и проверенным временем, он теперь устаревает и часто заменяется современным Swift.

Относительно молодой язык с открытым исходным кодом Swift был специально разработан Apple для iOS и OS X. Он был выпущен для общественности в 2014 году и с самого начала считался простым и понятным языком.

Swift и Objective-C схожи в своих основных концепциях, таких как расширяемое программирование, динамическая отправка и позднее связывание.Разница в том, что Swift позаимствовал положительные черты Objective-C и C ++ и отказался от устаревших и сложных элементов. Это существенно повлияло на скорость разработки.

Одно из основных преимуществ Swift по сравнению с Objective-C заключается в том, что он быстрее благодаря современным функциям:

  • Generics и Функции высшего порядка делают код более многоразовым
  • Выбор типа и делает компилятор, а не программист, ответственным за безопасность кода
  • Ключевые слова из трех символов делают синтаксис менее подробным

В результате программисты могут писать меньше строк кода, чем в Objective-C, чтобы добиться того же качества и функциональности.Используя Swift, вы можете предотвратить большое количество сбоев и ускорить разработку.

По данным Statista, в 2017 году и Swift, и Objective-C были в списке самых популярных языков среди разработчиков программного обеспечения по всему миру. Первые имели минимальные преимущества перед вторыми.

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

Popular–programming–languages–photo Popular–programming–languages–photo

Источник: Statista

Тем не менее, среди двух нет явного победителя: некоторые исследователи подчеркивают, что Swift идет вперед ; другие доказывают, что Objective-C по-прежнему на ходу; в то время как большинство разработчиков согласны с тем, что оба языка важны и их нужно изучать.

Зачем использовать Objective-C?

Естественно, что у любой технологии есть свои достоинства и недостатки. Когда вы выбираете язык программирования, важно не только сравнивать его с другими языками, но и резюмировать его плюсы и минусы. Вот несколько веских аргументов в пользу использования Objective-C.

Плюсы

  • Многолетний Опыт . Язык используется более 30 лет. Такой длительный период использования положительно повлиял на его развитие и зрелость.Objective-C хорошо протестирован; в нем написаны миллионы строк кода; создано большое количество библиотек (в том числе с открытым кодом); доступна исчерпывающая документация и руководства. Это обеспечивает надежность кода и гарантирует, что ответ на любой вопрос можно легко найти.
  • Динамический набор текста . Эта функция помогает интерпретировать мышление разработчика и упростить код. Динамическая типизация повышает гибкость использования классов и не требует приведения типов каждой строки написанного кода.Следовательно, в процессе разработки можно изменить структуру и назначение классов.
  • Поддержка старых версий . Поскольку Objective-C не молод, он может работать с более ранними версиями iOS и macOS, облегчая создание универсальных проектов. Молодой Свифт не может похвастаться такой способностью. Более того, Obj-C плавно совместим с языками C.
  • Стабильность . Язык достаточно зрелый, и ему не нужно выпускать постоянные обновления или новые версии.Вы можете безопасно разрабатывать свое приложение, не опасаясь, что вам придется тратить дополнительные деньги и усилия на его перенос на новую версию каждые несколько месяцев.

Это причины, которые отвечают на вопрос «Зачем использовать Objective-C?» А теперь взглянем на некоторые недостатки этого языка.

Минусы

  • Крутая кривая обучения. Язык основан на принципах ООП и имеет сложный синтаксис, который трудно освоить новичкам. Код нелегко читать, что усложняет программистам.
  • Уменьшение количества разработчиков. Objective-C был невероятно популярен много лет назад, когда не было лучших альтернатив. Сегодня есть более легкие и простые в освоении варианты, и многие программисты отказываются изучать устаревший язык. Вполне возможно, что через пару лет количество разработчиков Obj-C сильно сократится.
  • Ограниченная функциональность . Естественно, что в языке, созданном несколько десятилетий назад, не хватает многих полезных современных функций, что часто приводит к снижению производительности.
  • Безопасность проблем. Зрелость языка, считающаяся преимуществом, имеет обратную сторону. Приложение, разработанное на Objective-C, могло бы быть более уязвимым для хакерских атак, поскольку многочисленные хакерские инструменты разрабатывались параллельно с разработкой языка.

Зачем нужен Swift?

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

Плюсы

  • Простота .Основная цель разработчиков Swift заключалась в создании простого языка, который мог бы легко освоить каждый. Они успешно достигли этой цели. Код Swift ясен и лаконичен. Это приводит к другим преимуществам, таким как сокращение времени разработки и простота обучения для новичков.
  • Открытый исходный код. Swift не требует лицензионных отчислений и может использоваться как коммерческими, так и некоммерческими компаниями.
  • Безопасность. Приложения в Swift менее уязвимы для сбоев и ошибок из-за таких функций, как общие, дополнительные и вывод типов.
  • Расширенный функционал . По сравнению с Objective-C Swift предлагает больше функций; в частности, оптимизированное управление памятью, поддержка динамических библиотек, разграничение пространств имен. Он также может полностью взаимодействовать с кодом Objective-C.
  • Более быстрое развитие . Swift освобождает программистов от лишней работы. Они могут выполнить задачу, написав меньше строк кода, что экономит время. Более сжатый код означает меньше ошибок и избавляет от необходимости переделывать работу и исправлять ошибки, а также экономит время.В результате Swift обеспечивает более быстрый вывод на рынок и лучшую монетизацию приложений.
  • Возможность кроссплатформенной разработки. В 2016 году Google объявил, что скоро Swift будет доступен для разработки под Android для мобильных устройств. Некоторые успехи уже есть. Swift, вероятно, превратится в кроссплатформенный язык, а это означает, что его внедрение будет расширяться, и все больше ИТ-компаний получат от него выгоду.

Минусы

  • Постоянные изменения. Swift по-прежнему является «сырым» продуктом, требующим улучшений и обновлений. Следовательно, самым слабым местом разработки на Swift является необходимость частого перехода на новейшие версии, что требует денег и времени.
  • Более ранние версии не поддерживаются . Опять же, поскольку Swift молодой, он не поддерживает версии ниже iOS 7.0 и macOS 10.9. Следовательно, невозможно создать универсальные приложения, поддерживающие все платформы.

Различия между Objective-C и Swift

Мы составили диаграмму, чтобы вы могли быстро сравнить эти языки.

Сравнительная таблица: Различия между Objective-C и Swift

Objective–C–vs–Swift–comparison–image Objective–C–vs–Swift–comparison–image

Bottom Line

И Objective-C, и Swift могут использоваться для выполнения определенных задач благодаря ряду присущих им преимуществ. Выбрать явного лидера пока сложно. Хотя Swift прост, он все еще находится в процессе разработки и требует многочисленных улучшений. Objective-C, в свою очередь, является стабильным и продуманным инструментом, но он загружен множеством устаревших функций.

Если вам нужна помощь в принятии решения, что выбрать для вашего проекта iOS, SaM Solutions может вам помочь. Наш опыт разработки включает в себя различные технологии и инструменты, в том числе Swift и Objective-C.

SaM Solutions предлагает широкий спектр услуг: консультации, планирование, сквозная разработка, тестирование, реинжиниринг и дальнейшее обслуживание. Свяжитесь с нами, чтобы обсудить ваш проект или у вас возникнут вопросы.

Голосов пока нет.