Pull to refresh

Comments 235

Забыл вариант ответа в опросе — «Проект — говно, пускай Ларс Кнолл сначала научится кодить» :(
Скорее «C++ я вижу только в страшных снах»
C++ тоже недолюбливаю, но QT хорош не смотря на него :)
Наверняка все подумали именно про QuickTime, ведь контекст отсутствует.
Я подумал про QuickTime. Еще спросил себя, причем тут C++ и quicktime? Там же наверняка половина на С, а другая на ObjC.
Это принципиально. Qt — это кьют и нету разницы в контексте.
UFO just landed and posted this here
Опросник о Qt, а не о С++, не нравится С++, ну, пользуйтесь PyQt
Да кокой на фиг C++ — там давно QML да JavaScript.
Если приложение сложнее калькулятора или агрегатора RSS, то это уже комплексное приложение, не без С++
Это был сарказм по поводу поддержки нативного кода в GUI на мобильных платформах. Собственно, начиная с MeeGo виджеты там стали неюзабельны.
Есть биндинги для Python, правда не скажу точно насколько актуально и кроссплатформенно.
Вполне актуально и кроссплатформенно
UFO just landed and posted this here
Не говоря даже о документации.
Неистово плюсую. Для меня доки по qt — это пример того, как надо нормально документировать фреймворки, библиотеки и языки.
С более грамотной документацией ни разу не встречался. У Miscrosoft .NET, в принципе, тоже хорошо сделаны, но до Qt им ещё очень далеко.
Вы не поверите, сколько времени я потратил, чтобы мое исправление доков пустили в master. С пятой попытки, только после жесточайшего review
По поводу ревью, согласен, очень жесткое. Постоянно слежу за одной парой Laszlo Papp и Denis Shienkov, и их реджекты друг другу.
Не поленитесь, почитайте историю комментариев к этим ревью, особенно ранним. Я еще молчу о их войне на багтрекере.
Некоторые правда ревью там где под сотню комментариев уже прошли, но и этих хватит.
Список ревью
Собственно, что хотел сказать. В споре рождается истина, в нашем случае — хороший код.
Стыдно за кривой английский только. Глаза можно сломать.
UFO just landed and posted this here
UFO just landed and posted this here
Емнип, Qt отказались от исключений еще в Qt 3, и на это были весьма весомые причины.
UFO just landed and posted this here
Исключительные.
А какие причины использовать?
Использовать или нет вопрос религии и подхода к обработке ошибок. Извечный холивар.
Когда-то давно, когда компиляторы плюсов еще были тупые и неотесаные, использование исключений несло с собой заметный performance penalty даже в основной ветви (без исключений). Но с тех пор какбэ изменилось очень многое.

Исключения в плюсах на сегодня на десктопе использовать нужно. Объективных причин использовать много: это единственный совместимый с RAII способ обработки ошибок, единственный способ выбросить ошибку из конструктора, и этого от вас ожидает STL. Причины не использовать все именно что религиозные, из разряда «деды так писали, и мы будем».
В принципе RAII можно и с кодами ошибок использовать, конечно if придется писать каждый раз.

auto data = std::unique_ptr<MyClass>(new MyClass);
...
if (FAILED(hr))
  return hr;
...
return S_OK;


ИМХО мне кажется исключение некоторые не любят потому что:
* Pokemon Exception Handling стараются не использовать так как все знают что это плохо, а выяснить какие исключения может бросить метод порой сложно (особенно в сторонних библиотеках). Поэтому многие пишут обработку исключение то если у него на машине что возникло, что приводит к падению у клиента на исключениях которые можно было легко игнорировать. С кодами ошибок приходиться везде писать if (FAILED(..)) return и это считается нормальной практикой.
* Исключения есть проблемы при бросание за границы Dll, особенно если используются разные компиляторы. stackoverflow.com/questions/5107948/throwing-c-exceptions-across-dll-boundaries
Можно, да не совсем. Как вы в коде выше будете проверять на ошибку в new MyClass? Можно, конечно, нагородить фабрики, но они-то все равно в итоге будут звать конструктор, у которого нет возможности вернуть ошибку вместо объекта.
Ну да, придется писать Microsoft way как Direct3DCreate9 и т.п.
HRESULT CreateMyClass(MyClass** ppData)

Даже WinRT вроде возвращает HRESULT, исключение из него делает специальная магия в компиляторе.

Ну в любом случае не получиться использовать исключения если это будет распространяться как Dll которую могут вызывать используя другую версию компилятора.
UFO just landed and posted this here
Вообще нынче правильно спрашивать «осилили уже отказаться от исключений?», поскольку во всё большем количестве мест исключения в С++ считаются плохим тоном (см. гайдлайны от Гугла, например), а в последних стандартах С++ и вовсе, например, исключение, брошенное в деструкторе — даже не скомпилируется.
UFO just landed and posted this here
Ок, вот есть у вас Qt модель. На которую сверху навешна прокси. А сверху еще прокси. И что-то в самой глубине пошло не так при получении данных, например. Как сообщить клиенту, что произошла ошибка? Что вы будете длеать без исключений?
Сигнал\слот на onError, захочу — подпишусь, не захочу — проигнорирую.
У кого сигнал слот? Клиент видит только верхушку моделей. Через стандартные прокси его не протащить. Вам тогда придется дополнять интерфейс моделей (причем неявно), отходить от стандарта, что не есть хорошо.
Ну подождите, если мне нужно знать о том, что что-то важное в модели пошло не так и она сейчас в каком-то странном состоянии — то это часть модели. Об этом должен быть или код возврата, или оповещение ивентами.
Вы понимаете, у вас что-то не так пошло в исходной модели, а сигнал вам нужно пропихивать через модель сортировки, например, которой вообще не надо знать о том, что в исходной модели данных что-то пошло не так. Но с другой стороны, вы должны работать с моделью данных только через стек прокси и ссылка на самую нижнюю модель вам не только не нужна, но и вредна (чтобы не было соблазно работать с ней непосредственно).
Унаследоваться от QAbstractItemModel и писать какие душе угодно сигналы, что тут нестандартного?
И свою иерархию прокси тоже?
Да, если нужно передавать инфу вверх о том, что внизу что-то пошло не так. И иерархия проксей может быть унаследована от одного прокси.
Стандартный прокси уже есть QAbstractProxyModel. И в него нельзя засунуть еще один сигнал. А от него уже унаследованы станадртные прокси, вроде sort/filter и identity. Вам их переписывать прийдется. Это не халява причем. И клиенты будут негодовать, что стандартные прокси нельзя в вашу иерархию засунуть. И еще раз, принцип Single Responsibility протестует против того, чтобы модель сортировки занималась транспортом ошибок, а не сортировкой.
Спасибо, я в курсе. Вы не заметили словосочетания «если нужно» и говорите о случае когда это не нужно, и я с Вами согласен.
По мне сигнал об ошибке из модели надо подключать к некоему объекту логеру из которого доставлять сообщения куда угодно — в файл, в бд, в ui, в shared и в другие места.
Так вот при использовании исключений не нужно городить огород.
Огород? Исключения сами по себе являются огородом. Вам бы Спольски почитать, что-ли… ;)
омг… и как вы будете поддерживать состояние процесса во вменяемом (т.е. — предсказуемом, со всеми инвариантами etc) состоянии, если ошибки так легко игнорировать?

как вариант, можно послать сигнал.
UFO just landed and posted this here
Ну как раз там написано, что они считаю что исключения лучше, но не используют по историческим причинам.

On their face, the benefits of using exceptions outweigh the costs, especially in new projects. However, for existing code, the introduction of exceptions has implications on all dependent code. If exceptions can be propagated beyond a new project, it also becomes problematic to integrate the new project into existing exception-free code. Because most existing C++ code at Google is not prepared to deal with exceptions, it is comparatively difficult to adopt new code that generates exceptions.
Ну то есть «если вы начнёте проект на С++, который не будет использовать ни одну из существующих в мире библиотек, ни сейчас ни в будущем, со 100% гарантией — вот его надо будет написать с исключениями».

Как это Вы себе такой проект представляете?
Проблема есть только когда код без исключений использует библиотеку с исключениями. В обратном случае достаточно проверить коды возврата «на границе», и пребразовать их в исключения.
А вы не думали, почему гайдлайны гугла запрещают исключения? Возможно, потому, что гайдлайны создавались тогда, когда с исключениями было гораздо больше проблем, чем сейчас?
Ну, во-первых, они пересматриваются регулярно (вон там уже какая ревизия), во-вторых — чего это такого стало лучше с исключениями «сейчас», чем было «тогда»?
Нельзя кардинально их менять на середине проекта. Иначе начнется полный бардакв коде. Они теперь так и будут без исключений, скорее всего.
Ну так и прекрасно! Это одна из самых проблемных областей, на самом деле. Их бросают где не надо и не бросают где надо. Их ловят где не надо и не ловят где надо. Их бросают одного типа, а ловят другого. Их ловят через catch(...). Вызывая какую-то функцию из сторонней библиотеки каждый раз думаешь «а как же тут не налажать с исключениями», а поскольку таких библиотек много — обязательно налажаешь.
Это вы про коды ошибок?

Нет, серьезно, можно сказать в точности то же самое про коды ошибок.

Разница, возможно, в том, что если ошибки обрабатываются через исключения, то в случае, если их не поймали, программа падает, а если через коды ошибок, то тихо не работает.
С кодом ошибки всё ясно — если функция его возвращает — его надо сразу получить и обработать. Какие ещё варианты?

А с исключениями начинается чехарда: «А может функция внутри их сама ловит и обрабатывает?», «А может пробросить его наверх и обработать там?», «А может просто написать catch(...) и забить?», ну и конечно есть шанс просто забить и словить креш. Намного большее зоопарк неправильных решений, намного более непредсказуемы последствия.
С кодом ошибки всё ясно — если функция его возвращает — его надо сразу получить и обработать. Какие ещё варианты?
* Забиыть и не обработать
* Не понять, что эта функция возвращает код ошибки. Ну, то есть, не очевидно, то функция strchr возвращает 0 в случае, если символ не найден. Можно просто пропустить этот кейс.
* Бывает, что функция вообще не возвращает код ошибки, и после ее вызова нужно вызвать другую функцию, чтобы проверить, была ли ошибка (см. обсуждение выше. Сигнал вообще может дойти до вас уже после того, как все ваше состояние уйдет в разнос из-за ошибки).

«А может пробросить его наверх и обработать там?»
А кодом ошибки такого уже не бывает что ли?

Мне кажется тут уже чисто психологически — код возвращаемого значения в прототипе функции стоит первым, в функции int SomeFunc(); нужно ну очень постараться, чтобы не заметить слово int и не поинтересоваться, а что же оно означает.

А теперь заметьте\поймите стратегию этой функции по генерации исключений? Да просто даже на мысль о них ничего не наталкивает.
Основная проблема в том, что в результате получается код с кучей if-ов:
if (!SomeFunc()) {
  return SOME_ERROR;
}
if (!SomeOtherFunc()) {
  return SOME_OTHER_ERROR;
}
...

В итоге даже такие тривиальные конструкции, как if (foo() && bar()) становится невозможно писать — ведь там тоже могут быть ошибки, и их надо проверять. И в коде получается больше половины рутинного, повторяющегося мусора, который ничего не делает, кроме проверки ошибки и её пробрасывания выше (потому что в 90% случаев — таки да, ошибки обрабатываются на несколько уровней выше, чем они возникают — потому что тот код, в котором вылезает, скажем, ошибка чтения файла, понятия не имеет о том, в какой высокоуровневой операции он участвует, и как её корректно откатить, например).

Потом, грабли с тем, как именно, собственно, возвращать ошибки. У кого-то 0 это success, а остальное — коды ошибок. У кого-то >=0 это success (плюс какой-то значимый результат), а ошибки ниже нуля. Кто-то вообще выставляет код ошибки в thread-local переменной. В итоге народ постоянно путается, и пишет ошибочные проверки.

Что касается исключений, то про них надо просто понять: с т.з. семантики, это такие же возвращаемые значения, как и обычный return, просто автопроброс делается за вас. Или, если посмотреть с другой стороны — это монада, и все функции в плюсах на самом деле возвращают не X, а Success X | Error Y, и все операции с Error дают Error.
Да ну ладно, если каждый вызов функции заворачивать в try...catch — каша получается не меньшая. А если заворачивать блок кода с несколькими функциями — вот мы уже теряем часть контекста, поскольку разные функции могут бросать одинаковые исключения.

Пробрасывание исключения наверх, конечно, выглядит в коде лучше (просто не надо ничего писать), но это ведь по-сути неявное поведение — мы видим вызов функции, а подразумевается, что тут еще летают туда-сюда какие-то исключения (каких типов? из каких функций? кто их словит? а точно ли словит?). Знаете есть такое правило — «явное лучше неявного». Вы с ним согласны?
Плюсовые гайдлайны гугла написаны людьми, у которых психика искалечена джавой. Им простительно писать такие вещи, но воспринимать их всерьез не стоит.

В современном C++ от исключений отказаться невозможно. Просто в силу того, что они требуются стандартом языка. И даже если вы будете использовать new(nothrow), этого не будет делать STL. И если вы не будете бросать исключения в ваших конструкторах копирования в случае невозможности соблюсти инварианты — то ваши классы несовместимы с STL.
Полноценная поддержка Android *
Полноценная поддержка iOS *

Неужели мы дожили до настоящей нативной кроссплатформенности?
Помнится, еще до покупки Nokia году в 2007 были тестовые сборки Qt под Windows Mobile, тестировал на своей Toshiba G900, но тогда все дико тормозило и интерфейс был десктопный с плавающими окнами.
Я вам больше скажу, на Qt DevDays '13 Ларс обещал поддерку Windows Mobile в Qt 5.3.

Пройдет немного времени и нативщики будут попросту не нужны. Какой смысл держать пять разработчиков для пяти разных платформ, если можно держать одного джедая Qt, который будет все компилить под нужный target в мгновение ока (очень грубое и некорректное сравнение, но все-таки)? Прискорбно, но факт.

Тем более, QML позволяет даже самым отдаленным от С++ людям делать интерфейс. Я слышал, что даже есть команды с «фронтендерами», которые чисто не вылазят из QML и пялят реально очень мощный интерфейс в короткие сроки, а все ядровые фичи пилятся джежаями, после чего встраиваются в QML :)
на Qt DevDays '13 Ларс обещал поддерку Windows Mobile в Qt 5.3.

Windows Phone наверное все-таки, вряд ли кто-то станет вкладывать усилия в поддержку Windows Mobile в 2013 году :)
Точняк. Ух уж вы, сбили меня с толку :D
UFO just landed and posted this here
UFO just landed and posted this here
Человек просто немного не понимает, что суть полностью поменялась. Начиная с ядра и заканчивая юзер экспириенсом
Вообще-то Windows CE в Qt 5.2 поддерживается.
К сожалению, пока это будет C++, то этого не будет. Я вообще плохо понимаю людей, которые делают бизнес-приложения на нём. Понимаю там игры, видеоредакторы (где требуется высокое быстродействие и доступ ко всем фичам). Но обычные приложения…
Well, чистый язык, структурированный. QML позволяет делать интерфейс за считанные минуты. Привязать морду к ядру — беспонтовая затея.
UFO just landed and posted this here
UFO just landed and posted this here
Какой-то детский максимализм. А то не видели тормозных программ на плюсах и быстрых на C#/Java/Python/Web.
Ну так есть PyQT если на плюсах не хотите.
Пройдет немного времени и нативщики будут попросту не нужны. Какой смысл держать пять разработчиков для пяти разных платформ, если можно держать одного джедая Qt, который будет все компилить под нужный target в мгновение ока

Это вряд ли. Для игр и подобных вещей да, уже сейчас распространены Xamarin, Unity и т.п. Qt здесь может дать более высокую производительность, но многих отпугивает C++ (хотя с фишками Qt гораздо удобнее конечно, но все равно далеко не Java, .NET и Python).
Но если нужно API, или нативный стиль приложения, то зачастую проще держать специалистов под каждую платформу отдельно хотя бы на UI. Внутреннюю логику, разумеется, дублировать нет смысла.
API — элементарно встраивается в любое приложение. Добавили .mm, собрали clang'ом и у нас уже есть приложение, использующее акселерометр.

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

Лол. Если вы в гайдлайнах видите только внешний вид кнопочек, то мне вас очень жаль…
Нет же, конечно же, нет. Диалоговые окна, стандартные виджеты — все подстраивается. Другой вопрос, как дизайнер подходит к вопросу
В Qt элементы UI не нативные, они просто пытаются выглядеть как нативные на каждой из ОС. (ну, кроме KDE, Blackberry, SalfishOS и частично остальной Linux)
Ага. Страшно представить, но тот же ComboBox со стрелочкой и выпадающим списком, весь отрисовывается «вручную».
А какая разница, если юзер их не может отличить?

Кстати, WPF, например, тоже все свои виджеты рисует сам. Хотя, казалось бы, фреймворк только под винду и от самого MS. Просто это реально дает куда больше гибкости.

Да и производительность нативных Win32-виджетов хромает. Рэймонд Чен когда-то написал об этом пост — что, если вам нужно, например, несколько тысяч виджетов, и вы создаете под них несколько тысяч HWND, то это все будет тормозить by design — а если надо, чтобы не тормозило, то рисуйте все сами. Но нативные виндовые виджеты — те же кнопки и комбобоксы — требуют по оконному хэндлу на виджет, они не умеют по-другому.

Занекропощу:


требуют по оконному хэндлу на виджет, они не умеют по-другому.

на этом был основан один способ крушения Win95/98, когда зловред просто начинал с дикой скоростью создавать окна (в глобальном смысле слова, а не в смысле диалогового окна), добиралось это дело до 65535 или около того и система радостно уходила в BSOD.

UFO just landed and posted this here
Расскажешь потом о нем?
Так. Статья обязательна. Не надо ждать пока завоюете мир. Пишите по ходу дела, что делаете и что получается. Всем будет интересно.
UFO just landed and posted this here
Ну или вы просто не осилили Java, C# или Python
UFO just landed and posted this here
>> То, что на привычных технологиях пишется на автомате, на менее привычных требует некоторого времени на раздумия и планирование дальнейших шагов.

Это очевидно. Когда говорят о том, что «на X это делается быстрее, чем на Y», то имеется в виду — при прочих равных. Т.е. программисты с равным уровнем знания и опытом обеих технологий.

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

«Давай, рассказывай нам, как ты разрабатываешь на C++ в 100 и более раз быстрее, чем на на чем угодно»
UFO just landed and posted this here
На C++ я разрабатываю приложения на много порядков быстрее

Ну вот это видимо ключевой момент.
А минусующим умникам и обличителям студентоты хочу сказать, что C++ прекрасно знаю (слово «прекрасно» следует читать так, как оно написано, реально очень много в своё время на нём писал и знаю очень хорошо, собственно это был первый язык, с которого я начал свою профессиональную деятельность), но вот сейчас мне в голову не придёт что-то на нём писать без серьёзной необходимости. Основной плюс — да, производительность (про стабильность поспорил бы). Минус — разработка занимает значительно больше времени, чем на языках с динамической типизацией. Ну только для этого надо хорошо выучить один из последних, вместо того чтобы ругаться, что кто-то там C++ не осилил.
UFO just landed and posted this here
> Приведите примеры превосходства динамической типизации перед статической?

Пожалуйста.
UFO just landed and posted this here
Нет, нормальные преимущества.
Для случаев когда надо маркировать отсутствие / присутствие — можно использовать, к примеру, boost::optional
  • Минимум дополнительных строк: переменные надо либо просто объявить без указания типа (JavaScript), либо вообще объявлять не нужно (отдельные диалекты Бейсика[1]) или не обязательно (PHP).
  • Соответственно, упрощается написание простых программ.
  • Повышается гибкость языка. Например, только динамический язык может иметь функцию eval(), вычисляющую значение произвольного выражения.
  • Ускоряет работу компилятора — а значит, производственный цикл «написать-проверить».
  • Автоматически даёт языку элементы метапрограммирования и интроспекции.
    • Другими словами: когда программист пишет функцию «отсортировать массив», функция сразу начинает работать для массива чисел, массива строк, массива объектов (метапрограммирование). Чтобы определить, возможна ли операция x.length, среде выполнения нужно знать, какого типа переменная x и есть ли у неё поле length; если подобные запросы может делать и сама программа, это и есть интроспекция.

  • Упрощается работа прикладного программиста с СУБД, которые принципиально возвращают информацию в «динамически типизированном» виде. Поэтому динамические языки ценны, например, для программирования веб-служб.
  • Иногда требуется работать с данными переменного типа. Например, функция поиска подстроки возвращает позицию найденного символа (число) или маркер «не найдено». В PHP этот маркер — булевское false. В статических языках это особая константа (0 в Паскале, std::string::npos в C++).


Поехали.
  • Scala передает вам привет!
  • Туда же
  • Эмм. REPL у той же скалки? И вообще eval внутри кода — это от сатаны.
  • Ага. И увеличивает время на отлов рантайм багов из-за того, что аргумент ВНЕЗАПНО стал строкой вместо числа. Прекрасный аргумент.
  • Нет, серьезно, посмотрите скалу.
  • ORM
  • scala> "zxc".indexOf("a")
    res0: Int = -1
    

    Зато в пыхе я должено постоянно писать МИЛЛИОНЫ ====== чтоб уж ТОЧНО быть уверенным, что там false, а не 0.


Какие-то не очень аргументы в этой статейке.
Вы сейчас с Википедией спорите? :)
O.o
Вы использовали википедию как аргумент, источник.
Слушайте, я не имею ничего против статически типизированных языков. Просто в некоторых случаях динамически типизированные лучше помогают решить задачу. Об этом речь.

Если не верите Википедии, посмотрите на мир вокруг: сайты сейчас делают в основном на динамически типизированных языках. А студентота вчерашняя от студентоты сегодняшней ничем не отличается.
сайты сейчас делают в основном на динамически типизированных языках


Давайте откровенно. Не на языках, а на языке. На пыхе. И лишь потому, что там порог вхождения стремится к нулю.
Ну Ruby и Python тоже сильно популярнее любого варианта с типизированным языком. C++ иногда используют как вспомогательный из-за производительности (но сайты целиком на плюсах — это большая редкость), Java свою нишу занимает, но в целом динамические языки явно доминируют.
Совсем не лишь. Я в свое время с огромным облегчением перешёл с плюсов на пых для разработки сайтов.
Зато в пыхе я должено постоянно писать МИЛЛИОНЫ ====== чтоб уж ТОЧНО быть уверенным, что там false, а не 0.

Ну вы нашли с чем сравнивать. Если уж приводите Скалу, то и сравнивайте с чем-то более приличным.
Что там кстати с метапрограммированием? Как насчёт вызова метода по строке с именем или добавления метода в существующий объект? Для общего развития спрашиваю, без подколов, т.к. Скалу не знаю.
Что там кстати с метапрограммированием?

Готов спорить, что лучше, чем где-либо еще (лисп динамический, а это минус =))

Как насчёт вызова метода по строке с именем

Строка известна в рантайме или на этапе компиляции? Если в рантайме, то сами понимаете, что это чревато ошибками и не приветствуется, но возможно. Есть даже аналог `method_missing`. Но это обычно не нужно и используется только из-за убогости системы типов языка, в скале же система типов одна из лучших имеющихся.
Если на этапе компиляции… при желании вообще можно сгенерировать набор классов по метаданным из БД или в скалу добавить совершенно другой язык… кстати о другом языке (и заметьте вся эта магия при компиляции).

добавления метода в существующий объект

Да легко! И типобезопасно. И контролируемо. В каждом куске кода IDE подскажет какую именно имплементацию доп. метода используешь. При этом в разных местах программы или разных библиотеках можно добавить разные одноименные методы и они ни чего не испортят и не будут конфликтовать. Все на этапе компиляции.

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

Ну вы про DSL и всё такое прочее? Да, это понятно, но я о другом, я-то как раз про рантайм. То, что можно менять код во время выполнения (ну например по результату выполнения запроса из базы данных, но вообще много сценариев) — это одна из любимых моих фич динамических языков. Вот её я часто использую, а DSL — ну сильно реже.
Смотря что подразумеваете. В scala можно скомпилировать a.myMethod(b) не проверяя есть ли `myMethod` у `a` и при этом сам `a` отреагирует на это в зависимости от внутреннего состояние. Но этим обычно не пользуются. Это и в C# есть, кстати.

Если же вы про совсем крайний случай, то в чем преимущество у a."method_$name"(b) над a(s"method_$name")(b)? В одном символе?
> В scala можно скомпилировать a.myMethod(b)

Ну вопрос-то не в этом. Если у вас уже есть написанный код (a.myMethod), значит имя метода вам известно, тут и правда смысла нет пользоваться (если известно имя метода, то известно и есть он или нет).
Если же вы про совсем крайний случай, то в чем преимущество у a.«method_$name»(b) над a(s«method_$name»)(b)? В одном символе?

Не понял этой записи. Давайте на джаваскрипте, его все знают. Условно вот такой вызов: a["method_" + name](b), у него есть аналог в Scala? Вот это я хочу понять, потому что это наверное самая частоиспользуемая мной конструкция из метапрограммирования.
val map = Map(
  "method_plus_2" -> { (_: Int) + 2 },
  "method_multiply_2" -> { (_: Int) * 2 }
)

val name = if (true) "plus_2" else "multiply_2"

map(s"method_$name")(3)
// res0: Int = 5


Если же вы хотите извратиться, то пожалуйста. Но помните, что в scala всегда найдется способ лучше. Этот я демонстрирую исключительно из-за того, как вы сформулировали задачу:

def wrap(a: Any) = new {
  def apply(name: String)(x: Object*) =
    a.getClass.getMethods.filter(_.getName == name).head.invoke(a, x:_*)
}

class Test{ def method_concat(s1: String, s2: String) = s1 + s2 }

val a = wrap(new Test)

val name = "concat"

a(s"method_$name")("A", "B")
// Object = AB


За такое вообще-то в приличном обществе канделябром бьют — всегда есть способ лучше.
Ну то есть в первом случае это не метод класса (что в мап можно запихать по имени — и так понятно, с этим и в плюсах проблем нет), а во втором то извращение, котороые вы привели? Ну как бы не впечатлило оба раза.
Как-бы а чем вас мап не устраивает? Если с объектом можно работать таким образом, то он вполне может иметь интерфейс аналогчный мапу. Обычно с объектами таким образом работать не надо. Вы кстати, так и не привели ни одного случая, где такое нужно.

А чем второй случай не устраивает? Метод wrap надо реализовывать только один раз. Чем он не устраивает? Приводит любой объект к нужному интерфейсу. Как он реализован совершенно не должно быть важно.

Недавно видел картнку с человеком, пытающимся рубить дерево бензопилой. Вы объясните зачем вам это может понадобиться — я вам дам способ лучше.
Как-бы а чем вас мап не устраивает?

А как же this? Если речь о внутренних методах класса, то его придётся передавать отдельным аргументом, лишний код и неудобно.
А чем второй случай не устраивает?

Ну всё тем же — лишним кодом. В джаваскрипте или руби этот врап не нужен, просто обращаетесь к любому методу по имени.
Вы объясните зачем вам это может понадобиться

Хорошо, есть веб-приложение с роутами (привязка к url), есть контроллер, у которого на роуты замаплены методы (/something/show -> SomethingController.show). Это элементарный случай, бывают более сложные, но реже. Напишите хотя бы изящное решение для этого.
В джаваскрипте или руби этот врап не нужен, просто обращаетесь к любому методу по имени.

Метод надо импортировать. В личке, кстати, был метод send, про который вы так же написали что «не впечатлил», хотя там ни каких дополнительных методов.

Есть контроллер, у которого на роуты замаплены методы

Боюсь вас удивить, но у той же J2EE это скорее всего делается аннотациями, при чем по умолчанию путь как раз совпадает с именем метода. К сожалению точно сказать не могу — не занимаюсь веб-разработкой, а рассказы про автоматическую генерацию wsdl и xsd по java классу без усилий со стороны разработчика вам не много скажут.

Если вам требуются специфичные для scala подходы… тут я опять не специалист, но давайте расскажу что знаю.
Для начала: а вы не боитесь давать доступ к любому методу контроллера? Там ведь кроме основных методов еще куча всего понапихана — мало ли что через monkey patch туда пришло? Ну да бог вам судья (я бы так рисковать не стал).

spray.io
Роутинг вы будете задавать как-то так
path( "something" / Segment ) { 
  case "show" => SomethingController.show
  ...
  case _ => // 404
}

Но я сразу вижу, что для вас это не изящно. Если бы мне такое пришлось делать, я бы воспользовался метапрограммированием и сгенерировал все case-выражения автоматически, выглядело бы как-то так:

path( "something" / Segment ) { 
  SomethingController.allMethods orElse {_ => /*404*/}
}


Или allMethods(SomethingController) — дело вкуса. В остальных scala web-фреймворках разруливается подобным образом.
а вы не боитесь давать доступ к любому методу контроллера?

И именно чтобы не давать используются конструкции типа $method_name = 'action_' . $request->action; $controller->$method_name();, которые для урла типа /controller/action вызовет метод controller->action()
Ну как бы не впечатлило оба раза.

Да, кстати, почему вас что-то должно было впечатлить?

Вы спросили можно ли на scala реализовать определенный паттерн, смысла которого я не понимаю (он очевидно запутан, приводит к ошибкам и наверняка не является лучшим выбором).
Я показал как это можно сделать. Настолько же лаконично.
Я показал как это можно сделать

Хорошо, принято. Понял, что можно.
Настолько же лаконично.

Ну нет же. Если рассматривать целиком объявление и вызов, то или не лаконично или не то.
Да, давайте в личку переходить, а то сейчас всю тему замусорим.
У вас претензии, кажется, не столько к динамической типизации, сколько к слабой — т.е. когда числа легким движением руки превращаются в строки, и наоборот. Откуда и идет все это мракобесие с == vs === в PHP и JS, и тому подобные вещи.

Для сравнения, в Питоне тип значения не меняется после создания, а автоприведения нет в мало-мальски сомнительных случаях. Т.е. сложить int и float еще можно, а вот int и str — уже никак, нужно явно конвертировать либо одно, либо другое.

Ну и метапрограммирование в динамических языках все-таки на порядки мощнее, чем в Scala, и даже в D. Потому что там метапрограммирование неизбежно ограничено временем компиляции, а в динамическом языке могут на лету определяться новые классы etc. Другой вопрос, насколько это реально полезно.
У вас претензии, кажется, не столько к динамической типизации, сколько к слабой

Таки к динамической. В свое время я тоже намучался от того, что в метод мой передавали объект другого типа с теми же методами. Комментарий к методу не спас (кто их читает?), а воспроизвести, не имея доступа к вызывающей стороне, я не мог.

Ну и метапрограммирование в динамических языках все-таки на порядки мощнее, чем в Scala, и даже в D.

Так может говорить только тот, кто не пробовал. Изменения в рантайме — жуткая не тестируемая лапша. Жизнь на бомбе. Как вы правильно заметили это не используется.
Метапрограммирование же в scala проверяется компилятором и ему можно доверять.

Ну и да, в JS, Ruby и других просто нет тех же инструментов метапрограммирования.
Элементарный пример: как вы на этих языках реалиуете что-то вроде scalikejdbc:
sql"select id from members where name = ${name}"

Это prepared statement, без конкатенации.

Ни или пример из этой статьи:
xml \\ xp"*[@attr = $name ]" // здесь нет конкатенации, это XPath с внешней переменной
// здесь конкатенация просто невозможна - это XPath с внешней функцией
xml \\ xp"*[$isAllowedAttributeOrText(@attr, text())]" 

Таки к динамической. В свое время я тоже намучался от того, что в метод мой передавали объект другого типа с теми же методами


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

Более того, то, что вы описали — это на самом деле даже не уникальная для динамической типизации вещь. Абсолютно такую же ситуацию можно получить в языке со статической но структурной типизацией — например, Objective Caml.

Так может говорить только тот, кто не пробовал. Изменения в рантайме — жуткая не тестируемая лапша. Жизнь на бомбе. Как вы правильно заметили это не используется.


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

И я не говорил, что это не используется. Я говорил о том, что это зачастую используется не там, где надо. Но это как обычно — чем мощнее инструмент, тем больше желающих его использовать не по назначению.

Ну и да, в JS, Ruby и других просто нет тех же инструментов метапрограммирования. Элементарный пример: как вы на этих языках реалиуете что-то вроде scalikejdbc:
sql"select id from members where name = ${name}"


В смысле, чтобы name брался из текущей области видимости? Это, все-таки, достаточно специфичная возможность, которой действительно много где нет. Про Ruby не скажу — не специалист; в JS метапрограммирование убогое, но там и сам язык кривой; в Питоне это вполне можно реализовать через inspect.
Абсолютно такую же ситуацию можно получить в языке со статической но структурной типизацией — например, Objective Caml.

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

В смысле, чтобы name брался из текущей области видимости?

На самом деле внутри `${… }` может находиться произвольное выражение, которое может быть вычислено в текущей области видимости. В том числе если само выражение реализуется через метапрограммирование.
При этом, естественно, парсить это выражение не нужно.
Если вы утверждаете, что в питоне такое возможно — готов поверить на слово, хотя сомневаюсь, что удобно (в скале гарантированно уложится в 10 строк).
А по поводу памяти: если сохранять инкапсуляцию и придерживаться правила «написал код выделения памяти — сразу же напиши код для ее освобождения»

То есть надо писать больше кода, так? Вот это и есть пример превосходства динамической типизации над статической. Меньше писать, меньше потом поддерживать.
UFO just landed and posted this here
Писать больше кода и требовать с пользователей платить за программы, которые дороже разрабатывать?
Собственно, да. Линейка оперативки не стоит каких-то запредельных денег. И покупается обычно намного реже, чем приложения.
Это если память не распаяна на плате смартфона или для установки более ёмкой линейки не придётся покупать новый ноутбук.
UFO just landed and posted this here
Ну то есть это нормально платить программистам на C++ меньшие зарплаты, чтобы выкроить дополнительное время для разработки приложения? Ну ок, нормально так нормально, вам как программисту на C++ виднее конечно.
UFO just landed and posted this here
А я ведь не просто так «того же мнения» придерживаюсь. Писал же я на C++, много писал, всё знаю и проходил. Что на C++ кодить дольше, чем на Ruby — это ну настолько аксиома для меня, что даже не знаю. Ну не пробовали вы всерьёз писать на динамических языках, сами же признались выше, тогда о чём разговор-то?
UFO just landed and posted this here
Писал года четыре назад, не знаю насколько он похож на современный. Может что и поменялось, но см. ниже мой комментарий на ту же тему.
Я три с половиной года писал на AS3, PHP и Python. Достаточно динамические языки для вас?

То есть по году на каждый или в какой пропорции? Просто если из этих 3-х лет 2.5 — PHP, то это скажем несколько отдельный разговор.
UFO just landed and posted this here
Сделаете мне сайт на C++? Разумеется, не дольше и не дороже, чем аналогичный на PHP? :)
UFO just landed and posted this here
Отнюдь! Для своих задач и PHP хорош. Но, пускай, с Python или Ruby: на C++ разработка простенького интернет-магазина (карточки товаров, корзина) сколько времени займёт? Хотя бы примерно?
UFO just landed and posted this here
А я вот не сомневаюсь, что на Python или Ruby будет гораздо быстрее. Я не предлагаю соглашаться со мной, но, быть может, вам самому, для себя будет это интересно проверить. Попробуйте ради интереса самый простенький сайт наклепать на C++ и на Python/Ruby. Чтоб прочувствовать.
UFO just landed and posted this here
И как именно они там сделали yield?
При этом, как показали эксперименты, профессионал C++ и профессионал Java пишут приложения с одинаковой скоростью.

Скорость в строках возможно и одинакова. Вот только у C++ этих строк на порядок больше в каком-нибудь энтерпрайзе или веб.
UFO just landed and posted this here
Qt — это прекрасно конечно (без шуток), но от необходимости описывать один класс в двух файлах он как-то избавляет? «Больше строчек» — это медицинский факт. А хорошие фреймворки и под другие языки есть.
UFO just landed and posted this here
Никто не запрещает, но объявленные в хедере функции компилятор воспринимает, как кандидаты в инлайны. Как там в итоге компилятор отработает, точно сказать конечно нельзя, но это очень жирная подсказка со стороны разработчика, так что это как минимум не то же самое, что писать в двух файлах.
Все компиляторы уже очень, очень давно забивают на inline (что явный, что неявный). Во-первых, потому, что все шаблоны неизбежно получаются авто-inline, что на практике далеко не всегда отражает желаемое, а во-вторых, потому что компилятор все равно почти всегда знает лучше. Бесполезнее inline — только register.
И да, так себе удобство прямо скажем. Структуру класса IDE и так подсвечивают, а прыгать по двум файлам — несколько сомнительное удовольствие и при чтении-то, а уж при кодинге особенно.
Попробуйте описать в двух .h-файлах два взаимозависимых класса (т.е. где методы одного вызывают методы другого, и наоборот).
UFO just landed and posted this here
Что именно — взаимозависимые классы? в тех же плюсах:
struct Foo {
  void DoBar(Bar* b);
};

struct Bar {
  void DoFoo(Foo* f);
};

void Foo::DoBar(Bar* b) {
  b->DoFoo(this);
}

void Bar::DoFoo(Foo* f) {
  f->DoBar(this);
}


Вопрос в том, чтобы раскидать код выше по двум хедерам…

А написать так, как я сказал, можно практически где угодно. В C# все можно вообще в один файл засунуть:
class Foo {
  public void DoBar(Bar b) { b.DoFoo(this); }
}

class Bar {
  public void DoFoo(Foo f) { f.DoBar(this); }
}

Ну можно сделать их шаблонами. В момень инстанцирования оба хедера будут включены.
Можно, но сам факт того, что это шаблон — будет виден пользователям API. Чтобы его спрятать (потому что в данном случае это хак — деталь реализации), нужно будет писать еще обертку сверху.
Если приложение не сильно затратное по ресурсам в целом, то абсолютно нормальный подход. Где требуется производительность/экономия памяти, там плюсы рулят, так с этим я как раз и не спорю.
Поправка: это конечно не к динамической типизации относится, это плюс языков с гарбадж-коллектором. Но в контексте противопоставления C++ / «другие языки» не принципиально, да и плюсы динамической типизации сводятся в основном к тому же самому «писать меньше кода».
UFO just landed and posted this here
А этот гарбэдж-коллектор умеет обрабатывать цикличные ссылки? А перемещать объекты в памяти?
UFO just landed and posted this here
Иногда все-таки циклические ссылки портят малину, и нужно кочевряжиться с weak_ptr.
Код освобождения памяти руками на плюсах писать не нужно. Ни в Qt (parent-ы менеджерят child-ов), ни в обычных плюсах (unique_ptr и прочие умные указатели).
UFO just landed and posted this here
Об этом, кстати, еще и сам Страуструп пишет, чтоб контейнеры использовали а не прямую работу с памятью.
Приведите примеры превосходства динамической типизации перед статической?

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

Как сейчас в плюсах решается проблема возврата одним объектом другого? Кто должен создавать возвращаемый объект и кто его уничтожать? А если цепочка вызовов во время компиляции не определена?

UFO just landed and posted this here
Минус — разработка занимает значительно больше времени, чем на языках с динамической типизацией.


let da holywar begin.

тайм бомбы в рантайме искать — то еще веселье в динамике, которое сжирает временнЫе ресурсы
Вот не знаю, по моим наблюдениям время на дебаг у меня как раз сократилось после перехода на динамические языки. Но допускаю, что зависит от специфики задач.
Собственно, это примерно как сказать: «на Ruby я разрабатываю более производительные приложения, чем на C++». Так не бывает. Ну то есть бывает, но понятно в каком случае.
Я с вами не соглашусь. На ассемблере я разрабатываю приложения на много порядков быстрее (и при этом они стабильнее), чем на C++ (при чем как десктоп, так и веб). Все дело в опыте. А то, что современная студентота неспособна осилить языки без типизации и с ручным управлением памятью, очень печально.
UFO just landed and posted this here
Еще бы хотелось вариант ответа «пользовался раньше, но теперь не пользуюсь».
UFO just landed and posted this here
Может здоровье уже не то? :)
первый раз я попробовал пхп с другом...
UFO just landed and posted this here
потому что .net больше понравился
UFO just landed and posted this here
Когда под Qt появится что-то вроде DevExpress, Telerik или ComponentOne, только тогда можно будет вернуться к вопросу «почему нравится больше?».
искал такой же пункт ответа но не нашел
Как это не печально осознавать, но до полноценной поддержки android-а еще долго.
На вскидку:
— Нет полноценной поддержки скалябельного интерфейса. Приходится городить кучу кастылей ( см. примеры прогноза погоды (у вас на банере) и неофициального ubuntu one клиента, которые пока единственные нормальные приложения на QML для андроида и iOS ).
— Дизайнер QML совсем плох, если делать нормальное приложение, то о нем можно забыть. Например в упомянутых выше приложениях быстро визуально отредактировать интерфейс невозможно.
— Работать с камерой в андроиде вообще толком невозможно. Побаловаться можно и все. Ничего толком с камерой не сделаешь.
— С другими нативными штуками такая же проблема. Взаимодействие с другими приложениями, интеграция и т.п. Везде придется делать кастыли через JNI.

Но однозначно новость позитивная…
— Можно по-подробнее? У меня все отлично работает, layouts хорошо ездят туда-сюда, в чем проболема?
— Дизайнером кто-то пользуется? :) Я его за год ниразу не открыл — декларативить же проще
— Работа над камерой, API для сенсоров и другими вещами стоит
— Да, порой действительно стоит такая необходимость
UFO just landed and posted this here
UFO just landed and posted this here
Насколько я знаю, Qt всячески оптимизируют и улучшают. Если бы qmake еще поддерживал ninja…
Можете, пожалуйста, ткнуть, что за ninja? Искал неправильно по всякому — гугл выдаёт мастеров ниндзюцу и сопутствующее.
так виджеты уже выпилили из QtGui в отдельный QtWidgets. Сейчас самая жирная релизная DLL — Qt5WebKit, ~17 Mb
О! Расскажите, пожалуйста, если вы в курсе, этот QtWebEngine заменит QtWebkit?
Пишут что разработка над Qt портом вебкита, который сейчас используется, уже прекращена, поддержка будет, не более. Все новые фичи HTML5 будут только в новом WebEngine. Думаю, дотянут вебкит до Qt6 а потом уберут поддержку.
Да, он уже заменил вебкит, но его пока боятся выпускать, потому что сильно нестабильнобаганный
UFO just landed and posted this here
Пруфы или обо**ан? Можно пожалуйста, конкретнее?
Да легко.
Возьмем «обычное» приложение на C++\Qt, использующее Qt только для GUI (ну и немного классов из Core, раз уж их все равно тянуть вместе с GUI). Собираем его с Qt 4.8.5 не статическим — получаем 150 Kb исполняемого файла, которому нужны QtCore4.dll (2.5 Mb) и QtGui4.dll (8.3 Mb) и C++ Runtime соответствующей версии.
Если собирать статически, то на выходе получаем исполняемый файл размером в 7,5 Mb, которому ничего не нужно. При этом для статической сборки Qt 4.8.5 тоже ничего, кроме компилятора, не нужно (если не собирать WebKit, Phonon и т.п.), и она вполне себе собирается без всяких патчей.
Теперь собираем то же самое приложение: те же 150 Kb исполняемого файла, Qt5Core.dll (3,9 Mb), Qt5Gui.dll (2,9 Mb), Qt5Widgets.dll (4,5 Mb) и тот же самый RT. Разница небольшая, но не в пользу Qt5.
Статически же собирать Qt5 — целое приключение. Кроме исходного кода, нужны еще Perl и Python (а если с опциями ошибиться, то и DirectX SDK). И то не факт, что вообще соберется. Каюсь, сборку 5.2 еще не тестировал, но уверен почему-то, что зависимость configure.exe от вышеупомянутых перла и питона никуда не делась.
Пользуюсь с момента выхода. С точки зрения десктопных приложений я не увидел какие то либо принципиальные улучшения. Есть прикольные вещи типа QCommandLineParser но в целом ничего прорывного.
А вот сборка под андройд существенно улучшилась. Если раньше были танцы с бубном, то теперь почти все работает из коробки.
Поддержка категорий логирования и file selector — очень даже нужные вещи.
А что, правда всё так радостно с кроссплатформенностью нынче? Я последний раз на Qt кодил во времена версий 4.что-то-там, и слово «кроссплатформенность» было тогда такой шуткой для своих. Но вообще Qt мне всегда нравился несмотря на. Кто последнее время собирал на нём что-то серьёзное под несколько платформ, не поделитесь, какая сейчас ситуация?
Да много их, этих проектов. Qt 5 не так давно вышел, ничего громкого не было слышно, но я уверен, что qutim.org/ портируют.
Нет, я понимаю, проектов-то много может быть. Я тогда тоже «портировал», но вот в этом слове немного и загвоздка. «Кроссплатформенность» предполагает, что портирование должно вообще-то сводиться к перекомпилированию.
Вы неправильно меня поняли. Портируют с Qt 4 на Qt 5. Если вам нужно именно ваще сразу без заморочек компилить приложение под нужный target — пожалуйста. Я позавчера таким занимался — запустилося на моем Nexus 4 и эмуляторе iOS
А, хорошо, спасибо. Буду надеяться, что светлое будущее настало.
Почитайте про QPA (Qt Platform Abstraction). С этой штуковиной, вы можете хоть в одиночку написать цель сборки для вашей микроволновки :)
Ну так понятно, что сварганить цель сборки можно при желании подо что угодно, вопрос-то в основном в том, насколько хорошо работают уже готовые. Поскольку ну мало кому придёт в голову дополнительно к разработке приложения ещё и разрабатывать/допиливать цель для Qt, что с учётом всех тонкостей платформы может занять больше времени, чем написать нативное приложение.
Прошу прощения, пропустил новость и поленился посмотреть. Спасибо большое за мессенджер, очень показательное приложение.
Странно я работал еще на Qt3 и кроссплатформенность вполне себе работала. Пусть некоторые вещи требовали доработки но совсем на мой взгляд небольшой. Гуи приложение успешно работало на винде, линуксе и маке.
Меня всегда мучил вопрос. Как Qt работает с камерой? Из доков гугла явно следует, что работать с камерой можно только из java API. Получается есть механизм работы с камерой, как с обычным девайсом в Linux?
В Necessitas (Qt for Android) есть поддержка выполнения нативного jni кода
Сорри, я немного запутался. Нативный код в данном случае Java или C++? То есть Qt не напрямую с камеры, как Linux — девайса фреймы забирает, а использует Java API?
Necessitas выполняет Java код, для работы с Android API
UFO just landed and posted this here
И вроде бы официальный Qt под Android основан на наработках Necessitas.
Да и еще Google Play Services и Google Maps. Врядли все это заведется без лютых костылей.
Я лично добавил в TODO лист GPlayServices на саммите, можете не волновать, будут в 5.3
Очень радует конечно, но есть несколько моментов, которые делают использование Qt не лучшим решением, как минимум под iOS:
— QML элементы ведут себя и выглядят совсем по другому, нежели родные Cocoa (списки, элементы ...), смотрится как-будто портировали KDE под iOS
— нет многих «нативных» плюшек: Notification Center, Background Multitasking, Push Notification, Core Location, Core Motion… для поддержки всего нужно будет костылять и писать прослойки. А бридж между Cocoa и Qt не такой и банальный. Я себе в одно время голову сломал
— количество готовых решений под Qt намного меньше, нежели под Cocoa, то-ли разработчиков меньше, то ли они с меньшим желанием делятся своими решениями
— отрисовка текста в Qt собственная и сильно отличается от Core Text, что делает приложения чужеродными. А текст — это один из основных элементов интерфейса.
— специалистов Cocoa сейчас уже намного больше, нежели Qt. Так что поддерживать и сопровождать код будет тяжелее
— на Cocoa писать приятней и быстрее, нежели на C++(пусть Qt это уже совсем другой C++, но идеологически и фактически это всё-же С++)
— нет нормальных инструментов для Qt для профилирования приложения: отрисовка, скорость работы, утечки памяти… Valgrind конечно же есть, но по сравнению с Instruments — это адский ад.

Не смотря на это всё я считаю, что Qt хороший инструмент для созданяи ряда кросс-платформенных приложений, та-же погода и всякие там корпоративные новостевые приложения, детские книги с анимациями, демопроекты, каталоги… И намного более перспективное решение, нежели Cordova или Titanium (и тем более лучше, нежели Adobe Air).

Но Cocoa touch и Android SDK очень быстро и динамично развиваются и поэтому ребята из Qt просто физически не смогут поддерживать все последние нововведения, поэтому Qt всегда будет находится на пару шагов позади мэйнстрима. И если в случае с андроидом это не так страшно, так как эволюция ОС происходит достаточно инертно (хотя гугл обещает постоянно это улучшить), то в iOS новая версия становится мейнстримом практически за месяц-два.

Поэтому я 20 раз подумаю, нежели использовать Qt, а не родные инструменты.
Мне кажется, что Qt там прежде всего для каких-нибудь внутренних приложений сгодиться, а не для ширпотреба в маркете. Когда проще и быстрее портировать, чем сложную программу для каждой оси заново с нуля писать.
Ну пока уровень именно такой :)
отрисовка текста в Qt собственная и сильно отличается от Core Text, что делает приложения чужеродными. А текст — это один из основных элементов интерфейса.

Для текста же можно включить нативную отрисовку или на iOS не работает?
У нас вот с коллегами возник спор по поводу возможности использования Qt на маке. Скажите, пожалуйста, существуют ли в природе Qt-приложения, по мак-версиям которых не было бы с первого взгляда видно, что они сделаны на Qt?
UFO just landed and posted this here
По поводу снижения производительности работы QML ничего не сказано.
Причина — смена всем известного движка V8 на движок собственной разработки. Все это написано в новости к релизу на сайте Digia. О причинах — читать там же.
Обещают в следующих релизах подтягиваться к производительности V8.

Про релиз QtCreator 3.0 тоже забыли указать.

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

Но после трех лет очень активной работы с Qt стал смотреть на него более реалистично. У него действительно есть ряд слабостей и скелетов в шкафах, о них нужно знать.
Если я хочу выпустить приложение под iOs, то динамические либы использовать нельзя. Как тут разруливается?
Читал форумы там обсуждают но ответа официального типа «Ребята собирайте прилаги на Qt под iOs и не парьтесь » так и не нашел.

Может кто в курсе что с лицензией?
Сравнение опенсорсной и Qt Mobile
qt.digia.com/Product/Qt-for-Mobile-Development/Qt-Mobile-Edition/Qt-Mobile-Comparison/
qt-project.org/legal.html

Как-то мне кажется, что опенсорс версия не совместима с Apple strore (((

ну тут и цены (((
qt.digia.com/Product/Qt-for-Mobile-Development/
qt.digia.com/Try-Buy/

PS
может кто-то реально в теме
можно ли использовать опенсорсную Qt в iOs приложениях при этом не открывая исходники самого приложения
Одно из основных преимуществ Qt в его интуитивности и единообразии, то, что называется solidity. Замечал, что там есть методы для всего, что только можно придумать. Можно сделать почти все, что нужно, и без грязных хаков и костылей. Документация обалденна, иерархия классов логична, конкретна и понятна. Инструментарий — без комментариев.
Sign up to leave a comment.

Articles