Pull to refresh

Comments 70

Проверьте пожалуйста текст спеллчекером, очень много опечаток. А так забавный текст для пятницы.
Спасибо за замечание! Действительно вышло грязновато — постарался исправить.
раньше действительно медленно работало автодополнение, подсветка глючила, но в последних версия все гораздо быстрее и меньше глюков, хотя иногда бывают
Ну если это все проблемы, то лучшую рекламу языку придумать сложно. Тот-же обратный эффект (может так и задумывалось), как от поста в защиту Go.
Читать такие статьи в любом случае интересно. Свежий взгляд реального программиста, попытавшегося что-то сделать на новом языке, лучше всего выявляет потенциальные недостатки этого языка, и вообще позволяет задуматься и подискутировать на многие интересные темы.
От себя могу сказать, что все те грандиозные фичи революционного языка, из-за которых стоит бросить Objective-C и начинать работать со Swift пока не несут на деле каких то революций — по сути у нас тот же Objective-C с небольшими приятностями, вроде чуть более прозрачного синтаксиса, дженериков, безопасности работы с памятью (за которую придется заплатить if let obtainedRef = ref {} на каждый чих для нуллабл референсов). И вот эти прекрасные дифирамбы производительности на абстрактных бенчмарках — да это интересно. Но чаще всего нам придется работать со все тем же Cocoa фреймворками, и эта разница с Objective-C не будет уже такой внушительной. И так со всеми фичами — вроде и здорово и классно, но с подводными камнями и легким ощущением обмена шила на мыло при внимательном рассмотрении. А платим мы за это производительностью и тем, что приходится работать с сыроватым компилятором. Видимо это больше проблема восприятия — эпл в привычной для себя манере обещает нечто грандиозное, а показало нам неплохой язык, но после изучения действительно свежих концепций привнесенных теми же Go/Rust и иже с ними, он кажется опоздавшим к празднику жизни.
Птичий язык не может быть хорошим. Сделал пару проектов на Свифте, плюнул и вернулся родное лоно Obj-C. Как козу продал…
«Птичий» по названию :), или таки есть интересные аргументы, которыми можно поделиться с сообществом?
Интересных нет, все обычно.
1) Не компилируется код после возвращения к проекту через полгода.
2) Нельзя вольно обращаться с типами данных.

И не надо меня клевать, птички). Свифт очень очень очень хороший язык, но лучше на нем работать года через джва).
А можете подкинуть какие-нибудь примеры про типы? ObjC не знаю, может, пропускаю чего?
возможно, имелось ввиду традиционное С\C++ приведение типов?
Эээ… Не может сложить два float'а… хорошо…

Не два Float, а два CGFloat. Если пишешь на Swift, то будь добр пиши на Swift. Т.е. используй родной Float, а не CGFloat, который перекочевал из ObjC и поддерживается просто для совместимости со старым кодом.

Между прочим, я проверил этот код в Swift 2.0 и он работает без проблем:

let width = 100.0
let angle = 45.0
let rad = width / 2 - 32
let ptX = CGFloat(width / 2) + CGFloat(cos(angle) * rad) // ptX = 59.45579579871914


Скорость компиляции постоянно растет. А скорость вашего кода может быть улучшена на несколько порядков если следовать простым правилам Optimizing Swift Performance.

На счет Expression is too complex to be solved at reasonable time... я без понятия. Никогда не встречал. Подозреваю, что это крайне редкий случай. Мог бы показать, что у него там такое монструозное.

И всё нечего больше сказать?
А вы присмотритесь чуть внимательнее — в тексте width — это не double, а CGFloat, пришедший к нам из недр SpriteKit. Именно поэтому ваш код собрался без проблем — по умолчанию Swift константу 100.0 сделает double. Многие бы и рады писать на чистом Swift, да внезапно вся махина Cocoa стала с точки зрений новых концепций языка легаси, а без нее Swift не самодостаточен. Именно в этом проблема, на мой взгляд, большинства дифирамб языку — они рассматривают прекрасный свифт в вакууме (а он действительно хорош), а не в связке с великим и ужасным Cocoa.
Странно, а я тут переписал чтобы width был CGFloat, и всё равно работает…

let widthDouble = 100.0 // Double by default
let angleDouble = 45.0 // Double by default

let width = CGFloat(100.0)
let angle = CGFloat(45.0)
let rad = width / 2 - 32
let ptX = CGFloat(width / 2) + CGFloat(cos(angle) * rad)


Вы на основе чего строите предположения, что Swift плохо работает с Cocoa?
Я вот пишу уже много месяцев на Swift и любые проблемы решаются в считанные минуты…
Значит нужно взглянуть еще внимательнее: делаете let angle = 45.0, и код не соберется. Кстати, обновив XCode (чего я делать конечно не хотел из-за его все большей тормознутости с каждым релизом. Но эксперименты — дело святое), я тоже проверил и к чести ребят из эпла теперь на этом примере ошибка выдается правильная. С другой стороны, я встречал и другие очень похожие проблемы с сокрытием ошибки приведения типа выражения внутренней конструкции внешней, так что не берусь утверждать, что проблема разрешена совсем.

Проиллюстрировать хотя бы одну из проблем с Cocoa могу вашими же словами:
Если пишешь на Swift, то будь добр пиши на Swift. Т.е. используй родной Float, а не CGFloat, который перекочевал из ObjC и поддерживается просто для совместимости со старым кодом.

Правильную вещь ведь говорите, только куда нам деваться, если UIKit стоит двумя ногами на Foundation, а там свои типы, пусть и в красивых оберточках, но это не double из Swift
А потом эппловцы в приказном порядке откажутся от старого апи, и боль и унижение придёт уже к объективщикам — переделывать CGFloat на Float )))
Я, честно говоря, тоже только что охерел. Думал, меня эта чаша не коснется… Но нет:


Расстояние между двумя точками, КАРЛ!!!
Ни фига себе! Набрал точно такую функцию в пустой файл на новом проекте — и, да, expression was too complex!
Для меня появление Swift было очень важным «за» в пользу начать писать приложения под iOS. Пробы на Objective-C меня сильно оттолкнули.
Конечно, Swift сейчас еще зеленый, да и выход Swift 2 не дает собрать уже имеющиеся приложения без большого числа правок, но хочется верить, что дальше все будет только лучше — мы точно нащупали дно)
Не знаю как для других, но для меня это был именно простой синтаксис.
Согласен, тоже начал писать под iOS с появлением Swift.
Конечно после Java & .NET видно что язык еще очень молодой и сырой, точнее 2.0 уже более-менее, год назад была хуже ситуация.
С ObjC связываться не хотелось, уж больно мне не нравится его синтаксис, а тут хотя бы более-менее привычный и перейти на него проще.
Точек с запятой нет, как в ФОРТРАНе, это бесценно.
Ну как в чем… Работодатели требуют :)

Когда количество контор где требуют Swift, перевалило (по ощущениям) за 30%, я понял что пора.
Ну, хотя бы писать
if(string == "somestring")

намного приятнее, чем
if([string isEqualToString:@"somestring"])

Плюс эти знаки собаки постоянные у строк. Простой синтаксис — это не так уж и мало в разработке. Однако ниже я написал неприятный момент со Swift из-зак которого продакшн-проекты я продолжу писать на Objective-C
Бред какой-то, не портите мне пятницу!
Есть еще один не очень приятный момент. Начал я как-то переписывать свой проект на Swift. После недели, в целом, комфортной разработки я заметил что билд долго грузится в TestFlight. Оказалось, что обычное приложение с 5ю вью контроллерами весит порядка 60 мегабайт. Поискав информацию в интернете, оказалось:
For the time being, Swift itself lives in the binary of each application built with it. This may change when Swift reaches a release that Apple is comfortable bundling with iOS, but for now it's just something we have to live with. This behavior is the reason you can build an iOS 7/8 application in Swift 1.0/1.1/1.2 and it just works when you build and run.

Больше информации.

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

P.S. Expression was too complex to be solved in reasonable time меня, конечно, тоже сильно улыбнуло, на всякий случай посмотрел в календарь, не 58-й ли год на дворе.
Хм… По поводу вкомпиливания рантайма в бинарник — интересно зачем? Чего нельзя сделать динамическую библиотеку в качестве временного решения (потом, как я понимаю, часть рантайма свифта как-то перетечёт в либы маковских осей… или я не правильно понимаю?).
Подозреваю, что свифт слишком молод и сильно меняется, ломая совместимость. Засунуть либы в ось это значит отказаться от обновлений частых и залочить все API — обновления не должны ломать ничего в приложениях, которые скомпилены для старых версий. А с этим у свитф не очень.

Как доживет до стабильно состояния, так и залочат. Тем более сами это говорят.
Это действительно печально, учитывая, что и сами эпловцы понимают важность проблемы толстых бандлов (в презентации On Demand Resources на WWDC вполне разумно расписали). Но тут наджеда на то, что язык устаканется действительно более-менее быстро.
Приложение на Swift 1.2 из 7ю вью контролерами (еще пару Navigation и Tab Bar) занимает 26 мегабайт, но там еще ресурсы (немаленькие изображения) занимают 8 мегабайт.
Статья от SEP 29TH, 2014, будем надеятся, что во 2ой версии, пофиксили эту «фичу».
В любом случае, для совместимости с iOS 7-8 рантайм должен будет продолжать поставляться с приложением
До сих пор не могут заставить себя перейти на него и даже начать баловаться с ним. Преимуществ самого языка — для меня их нет, objc прекрасно читается и пишется после долгого опыта работы с ним, а фичи меня ничем не подкупают — они ничего не меняют, а отчасти заставят лишь спотыкаться по первости. Все эти дженерики, ноннулаб переменные, хитрые энумы и прочие фенечки — все это забавно скорее для тех, кто начинает со свифта. Ну и конечно для меня ставит крест на любом применение факт нестабильности самого языка и общей глючности всего со свифтом связанного и тот факт, что он до сих пор требует тащить с собой тонну библиотек.
Swith без поддержки приватных членов класса, хм....

Какой ужас, как же без них жить то?
Если это был сарказм, то спрошу: инкапсуляция это по-вашему пустое слово, никак не связанно с ООП?
Инкапсуляция это не только модификаторы доступа. А их значение сильно преувеличено, по крайней мере когда речь заходит о скриптовых и скрипто-подобных языках.
А чем скриптовые и скрипто-подобные языки принципиально отличаются от любых других в смысле использования модификаторов доступа? Модификаторы доступа позволяют управлять вниманием читающего код программиста, указывают на то, какие переменные могут меняться в контексте определённого поведения… Да, это можно эмулировать другими средствами, но и ООП можно эмулировать в рамках функционального подхода. Зачем это делать прямо специально?

Единственные две видимые для меня причины, по которым модификаторы доступа не включаются в язык — это ускорение разбора кода программы и упрощение языка с точки зрения его изучения (только изучения грамматики — не написания кода). Если первую причину я ещё могу понять, то вторая — упрощение ради упрощения, чтобы программисту меньше слов языка учить нужно было — мне не очень ясна. Тогда нужно braindfuck учить — всего четыре, кажется, слова, вообще отличный язык.
Утрирую, конечно, но меня всегда удивляло отсутствие модификаторов доступа в некоторых серьёзных языках — в том же objective-C, например, в котором приходилось имитировать модификаторы, разбивая поля на те, что в m-файле (приватные) и те, что в хедере (публичные).
Справедливости ради, переход на приватные поля классов только в m файлах для меня только плюсы несет. А публичные поля только через свойства. Это и сокрытие реализации, и очистка интерфейса от деталей реализации. Естественно, рантайм все равно позволит получить все поля класса, где бы они не были.
Swift не ООП язык. А классы, мне кажется это временная штука, и с какого-то момента писать их станет моветон.
А что придёт на смену ООП? Что-то вроде прототипного подхода?
Обычные такие интерфейсы как в том же C# с поддержкой множественного их наследования — действительно удобно и, в общем-то, это ООП как оно есть. Собственно, протоколы это фича, пришедшая из Obj-C — он тоже не ООП теперь? Фишка Go не в том, что там интерфейсы есть, а то, что не нужна их явная реализация. Есть методы — значит реализовал.

Классы никуда не делись и в Go. Там просто нет наследования, но есть встраивание как костыль на замену. Структура с методами и интерфейсами — чем не класс. Никуда классы не денутся и из swift — это обычный мультипарадигменный язык, в том числе ООП, которое там обычное и всем привычное.
Обычные такие интерфейсы :) Структура не класс — можно например наследовать структуру?

Явная или неявная реализация это дело то десятое. Например в Go легко с этой неявной фигней попасть в проблемы, так что это не фишка, это беда, мое мнение. Но классов в Go нет. Нет, структуры это не классы. Нет, даже то что там где-то можно объявить нечто похожее на методы, не делает структуры ООП классами.

Протоколы это не фича из objc, это современный тренд, который повсюду. Просмотрите все языки которые в тренде — там везде так или иначе используется эта фишка вместо наследования. Вместо, не вместе.

Смотрел доклад по свифт эппловский — там основной упор на то как делать без классов. Так что классы это временное явление, чтобы голову сразу не ломать людям. Вам же скажи что ООП всё, ой что начнется. А тут все прилично — вот вам ООП, это прям практически привычный вам язык, видите, классы. Ничего страшного, вперед, это просто красивый objc, новенький, но такой же. Ой смотрите, а тут еще вот так можно, и нужно кстати, но вы пока не нервничайте, ООП тут, да, пока.

Одни только страдания народа за private явно это демонстрируют — нельзя вот так сразу сделать ООП всё, нельзя. Хотя всем уже стало понятно, что он всё, но будем это доносить постепенно. Apple умные, знают же что вот там сразу если вывалить истину, язык не полетит.
Это все какие-то гадания на кофейной гуще. ООП никуда нигде не делось. То, что модные языки немного по-другому его делают, ничего особенно не меняет. Swift в первую очередь мультипарадигменный язык, а что использовать будет пользователь уже его дело, а не Apple. Они просто перенесли все из ObjC и это именно его фишка, а не тренд, потому что им надо вообще сохранять обратную совместимость с их огромным ООП Cocoa. Никто это менять не станет, а значит и из языка это не исчезнет.

Что до Go, то единственная проблема там отсутствие наследования привычного — вместо наследования реализации используется наследование интерфейсов, что тоже вполне обычная вещь. Но все остальные атрибуты на месте в привычном виде — инкапсуляция, полиморфизм, абстракции. Даже можно заключить, что все является объектом, потому что интерфейсы можно реализовать даже для int.
UFO just landed and posted this here
В ObjectiveC этот момент классно решается разбиением кода на интерфейс и реализацию.
На самом деле, такое разделение в objective-С мне всегда казалось неудобным. Прежде всего из-за того, что приходится бегать по двум файлами — ведь как публичные так и приватные поля и методы могут использоваться в как публичных так и приватных методах.

Впрочем, при корректном проектировании кода такая проблема, скорее всего, не возникает.
Сплошной код класса на Swift после этого несколько дезориентирует. Может IDE как-то должна активно помогать в навигации по всему этому, но пока в XCode не больно много инструментов для этого. Переходы по методам/полям + //MARK:.
У свифта есть поддержка приватных членов класса
Эсли честно то статья немного опоздала, так как в Swift 2.0(Xcode 7) а то и в Swift 1.2 большинство проблем уже исправлено. Опциональные типы для членов класса удобная и безопасная вещь так как ты «точно» знаешь что может быть nil а что нет. Сначала немого непонятно было как с ними работать после Java 7(Android) но сейчас их очень не хватает когда пишу на Java 7. Насчет тормознутости Xcode 6.4 при работе со Swift 1.2 — есть немного, но Xcode 7 работает намного шустрее. Так же было бы интересно узнать как обстоят дела в AppCode при работе со Swift.
Да, хотелось бы узнать у автора, использовал ли он старый 1.2 или свежий 2.1?
И что публика скажет по поводу Appcode от JetBrains если использовать ее как IDE для серьезных проектов.
Сам только встал на этот тернистый путь изучения, ios разработки, года 4 назад был момент начать obj-c, но испугался и бросил, здесь же в swift, как показалось (после js) все чуть проще.
Думаю, для приложений аля заметки и напоминалку с красивым интерфейсом, он будет самое то.
AppCode шикарен, на Xcode возвращаться не захочется (ИМХО)…
Но есть одно «но»: я не использовал его для работы со Swift, хотя он его поддерживает.
ААа, т.е. только в связке с obj-c работали? Все же xcode, все еще какой то неповоротливый.
Судя по моим экспериментам и опыту работы со Swift, действительно это о Swift 1.2. На данный момент это и правда больше историческая заметка о молодых (читай лихих) годах свифта. Но честно говоря, субъективно и Swift 2 часто вызывает лично у меня ощущение, что компилятор играет против тебя — хотя здесь очень сложно оценить, где кончаются проблемы языка и начинаются проблемы восприятия разработчиком.
Пишу профессионально на Scala, писал пару недель на ObjC пять лет назад, на досуге почитываю Haskell и вот пару недель назад решил попробовать выучить Swift и написать чего-нибудь под iOS.
Так вот, лично мне очень понравились функциональные фичи языка: алгебраические типы данных (enum), map/filter/reduce, лямбды и др. И все это достаточно неплохо сделано, что позволяет вытворить всякие вещи, типа Swiftx/Swiftz.
А вот кстати интересный пример. В Swiftz есть операторы которые вообще не понятно как с клавиатуры вводить: •, ∪, ∩. По моему вменяемые разработчики должны такого избегать. Зачем это вообще в язык добавили? Чтобы кто-нибудь мог brainfuck.swift реализовать? :)
Эти операторы мне конечно тоже не нравятся, но всегда либо есть альтернативное написание, либо его можно самому добавить.
Зачем это вообще в язык добавили? Чтобы кто-нибудь мог brainfuck.swift реализовать?
А причем здесь язык? Это разработчики Swiftz выпендриваются. Сама возможность называть операторы/методы/классы с использованием всего многообразия юникода сейчас доступна во многих языках, это не есть проблема.
Это сплошная деза. Зачем же это делать? Это какая-то статья-провокация.
Сегодняшний Swift не имеет ничего общего с тем, что написано в этой статье.
Да, год с небольшим назад, когда Apple объявила о Swift, некоторые, конечно, решили, что им дают готовый, как всегда очень качественный продукт. Но Apple оказалась хитрее, ни для каких больших проектов Swift 1.0 никто и не предлагал.
Она заставила весь мир работать над отладкой языка Swift и очень оперативно реагировала на все хорошие предложения.
Долго сопротивлялась, но сделала очень красивую обработку ошибок в Swift. Одни операторы guard и defer чего стоят. Сейчас язык в очень хорошей форме и действительно c многими парадигмами: хочешь ООП, хочешь элементы ФП, а сейчас еще и протокол-ориентированное программирование. Он отличается от того самого первого варианта 1,5 годичной давности как мобильные телефоны 90-х годов прошлого столетия величиной с портфель от iPhone.
То что автор статьи поскулил немного 1,5 года назад еще понять можно. Но то, что переводчик выложил это сейчас можно объяснить только тем, что целый год переводил, перевел и выбрасывать жалко.
Objective-C здесь вообще не причем. Apple его очень любовно сопровождает, API фреймворков и для Swift, и для Objective-C абсолютно одинаковые. Программируйте на чем хотите.
Но программировать на Swift приятно — всем советую попробовать и есть замечательные фишки типа if #available(iOS 9, *) без которых уже трудно обходиться.
а сейчас еще и протокол-ориентированное программирование


Что такое протокол-ориентированное программирование? Разве протоколы это не обыкновенные интерфейсы из классического ООП?
До Swift 2, как в Objective-C, так и в Swift 1.x, протоколы содержали только декларацию методов (это то, о чем вы говорите).
С расширениями протокола (Protocol extensions) в Swift 2, протоколы теперь могут содержать наряду с декларацией, реализацию методов по умолчанию.
Часто некоторую функциональность необходимо добавить всем типам, которые подтверждают определенный протокол (интерфейс). Например, все коллекции (протокола CollectionType) могут поддерживать концепцию создания новой коллекции на основе преобразований своих элементов.
Если в расширении протокола CollectionType реализовать эту функциональность, то все типы, которые подтверждают протокол CollectionType, автоматически получат эту функциональность совершенно бесплатно.
Расширения протоколов лежат в основе нового подхода к конструированию программного обеспечения, заявленного Apple как Протокол-Ориентированное Программирование (ПОП), существующее в Swift 2 наряду с традиционным Объектно-Ориентированное Программированием ( ООП) и элементами Функционального Программирования (ФП). Оно должно преодолеть такие проблемы ООП, как «хрупкий базовый класс» и жесткость наследования (rigidity and fragility of inheritance), «проблему ромба» (“diamond problem”), неявное разделение ссылок на объекты, необходимость частого использования «кастинга» вниз (downcasting) в переопределенных методах.
в Swift 2, протоколы теперь могут содержать наряду с декларацией, реализацию методов по умолчанию.


В общем и целом, такое можно смоделировать на основе множественного наследования в С++. Если брать в качестве примера CollectionType, можно сделать интерфейс, в котором имеются абстрактные (чисто виртуальные) геттеры-сеттеры, которые используются для доступа к полям классов-наследников.

Но я, конечно, признаю, что от «может быть реализовано» до «может быть сделано удобно» расстояние огромное. В плюсах, наверно,, это будет намного более громоздко.
А сейчас то настало время на нем писать? Или опять боль на год + миграция на исправленный и обновленный в конце?

Кстати, на счет #available я не соглашусь.

Сейчас у нас есть «iOS, OSX, and watchOS». Не вижу в доке tvOS..., а ведь еще ходят слухи про CarPlay. У всех потенциально может отличаться API. И где гарантия, что разработчик библиотеки которую вы захотели использовать задумался, что кто-то захочет использовать её к примеру в watchOS, когда он делает её для своего iOS проекта? Да и как это будет выглядеть? #available(iOS 11, OSX 11.11, watchOS 3.1, tvOS 2.5, CarPlay 1.0, *)?

В Objective C проверка наличия API реализуется непосредственно проверкой возможности его использования, наличия селектора или класса. В общем случае такое решение может работать где угодно.
Ну, это вы загнули насчет #available. Если вы писали приложения, то наверно, знаете, что первое, что вы указываете при создании проекта, это либо приложение на iOS, либо на OS, либо tvOS, либо watchOS.
Так что они никогда не перемешаются.
Да, сейчас можно писать на Swift 2.1. Посмотрите мои Задания для стэнфордских курсов на Swift здесь. Есть очень не простые.
Единственное, где Objective-C выигрывает, — это вставка C кода напрямую в Objective-C. Но они над этим работают.
Сейчас адаптирую стэнфордские курсы на русском языке на Objective-C для iOS 9, и хотя API абсолютно одинаковые для Swift и Objective-C, несопоставимо легче писать на Swift.
А guard это по моему костыль для лечения Pyramid of Doom, болезни вызванной исключительно optionals. Или я что-то не уловил?
Не уловили. Это действительно здорово.
UFO just landed and posted this here
Sign up to leave a comment.

Articles