
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.21] |
![]() |
|
Страницы: (56) « Первая ... 12 13 [14] 15 16 ... 55 56 ( Перейти к последнему сообщению ) |
Сообщ.
#196
,
|
|
|
Цитата korvin @ Во-первых не пара и не тройка, попробуйте что-ли. Во-вторых, любой синтаксический сахар кому-то нравится, а кому-то нет. Это всего лишь один из вариантов применения строковых литералов в качестве параметра шаблона. На пару-тройку символов? Вообще погоды не делает. От каррирования и то больше разницы. |
Сообщ.
#197
,
|
|
|
Цитата applegame @ Это всего-лишь один из вариантов применения строковых литералов в качестве параметра шаблона. Сам сей факт не вызывает отторжения. А вот зачем запихивать в строку код - непонятно. Пример хоть покажите радикальной экономии символов. |
![]() |
Сообщ.
#198
,
|
|
Цитата applegame @ Во-первых не пара и не тройка, попробуйте что-ли. Ровно два: ![]() ![]() find!"a.key == b"(foo, 1) find!(a => a.key == 1)(foo) Ведь без строк нам не нужен параметр b. А если бы не !, то вообще один символ. |
Сообщ.
#199
,
|
|
|
Впрочем, что-то мы увлеклись строковыми предикатами, пример я привел, чтобы разъяснить как вообще работает компиляция строк, в качестве пояснения к вопросу
"Строковый" предикат - это простая строка. Предикатом его делает функция find, поэтому, естественно, никаких захватов контекстов нет. Для захвата контекста - есть обычные лямбды. |
Сообщ.
#200
,
|
|
|
Цитата korvin @ Если юзать предикат с одним параметром, то и в "строковом" варианте можно убрать b (пять символов Ведь без строк нам ненужен параметр b. ![]() ![]() ![]() find!"a.key == 1"(foo) find!(a => a.key == 1)(foo) правда лямбда может захватить внешний контекст, а строка нет: ![]() ![]() int b = 1; find!"a.key == b"(foo); // ошибка find!(a => a.key == b)(foo) // все ок Доступен, опять же синтаксический сахар, который, лично мне нравится: ![]() ![]() foo.find!"a.key == b"; Добавлено На сягодня я заканчиваю. Завтра расскажу о других, не менее интересных для обсуждения, возможностей D. ![]() |
![]() |
Сообщ.
#201
,
|
|
Цитата applegame @ Доступен, опять же синтаксический сахар, который, лично мне нравится: Смотри сахарный диабет не заработай. |
Сообщ.
#202
,
|
|
|
Цитата applegame @ Доступен, опять же синтаксический сахар, который, лично мне нравится Пока такие "киллер фичи" будут продвигаться новыми языками, у C++ обеспеченное будущее. |
![]() |
Сообщ.
#203
,
|
|
Я что-то не пойму, об чём холивар. Если не ошибаюсь, поправьте, если не если, Александреску задумал D не как убийцу C++, а как язык с ориентацией на парадигму обобщённого программирования и без груза обратной совместимости с чем бы то ни было, а значит и лишённого набившего в C++ оскомину. Так что по определению везде, где требуется ниша мета- и К°, D наверняка предложит сырец покрасивше, где требуется "железный" уровень абстракции, он сольёт, в остальных случаях будет пофик. Остаётся только вопрос практичности результата там, где D якобы превосходит. Собственно и всё. А вы тут какую-то хрень обсуждаете.
Возвращаясь к интерфейсам. Интерфейсы в Плюсах всю жизнь прекрасно эмулировались виртуальными базовыми абстрактными классами. Невиртуальный базовый класс, неважно, абстрактный или нет, однозначно не используется как интерфейс. Всё это превосходно дружит с множественным наследованием реализаций. Какие ещё могут быть тут вопросы? Разве что к D. applegame, приведи пример простенького сериализатора на D. Кто не ходит в Общие Плюсы, вот ссылка на предмет измерения длины. Для понять, откуда ноги, там есть первая страничка темы. Интересно посмотреть на D-код в контексте, где он должен быть на коне. |
Сообщ.
#204
,
|
|
|
Цитата Qraizer @ Претензия к D, что у него якобы интерфейсы реализованы не совсем так как привычно (ссылаются на прочие языки с интерфейсами). А именно с одной особенностью. Тут не важно виртуальный базовый класс или нет. Виртуальность ничего не меняет:Возвращаясь к интерфейсам. Интерфейсы в Плюсах всю жизнь прекрасно эмулировались виртуальными базовыми абстрактными классами. Невиртуальный базовый класс, неважно, абстрактный или нет, однозначно не используется как интерфейс. Всё это превосходно дружит с множественным наследованием реализаций. Какие ещё могут быть тут вопросы? Разве что к D. ![]() ![]() class IFoo { virtual void f() = 0; virtual void g() = 0; }; class Base { void g() {} }; class Derived : public Base, public virtual IFoo { void f() {} }; int main() { Derived derived; // ошибка, Derived - абстрактный } ![]() Добавлено Цитата Qraizer @ Окай, ща набросаю чего-нибудь. applegame, приведи пример простенького сериализатора на D |
Сообщ.
#205
,
|
|
|
Цитата Qraizer @ Если не ошибаюсь, поправьте, если не если, Александреску задумал D не как убийцу C++, а как язык с ориентацией на парадигму обобщённого программирования и без груза обратной совместимости с чем бы то ни было, а значит и лишённого набившего в C++ оскомину. Ну автор темы не Александреску. Решили поспорить о D vs C++, почему бы и нет ![]() ![]() Цитата Остаётся только вопрос практичности результата там, где D якобы превосходит. Собственно и всё. А вы тут какую-то хрень обсуждаете. По большому счету именно этот вопрос мы и обсуждаем. Что могут дать возможности D и стоит ли оно того. |
Сообщ.
#206
,
|
|
|
Цитата Qraizer @ applegame, приведи пример простенького сериализатора на D. Набросал сериализатор/десериализатор. Постарался максимально обобщить, но возможны косяки. API простой, как пять копеек: ![]() ![]() stream.serialize(arg1, arg2, arg3 ...); // сериализует аргументы в stream, stream - любой объект для которого выполнима операция stream.rawWrite(const byte[]) stream.deserialize(arg1, arg2, arg3 ...); // десериализует аргументы из stream, stream - любой объект для которого выполнима операция stream.rawRead(byte[]) Из коробки поддерживаются: скаляры, массивы, структуры, классы. Классы и структуры сериализуются поле за полем, причем поля тоже могут быть классами или структурами или массивами и т.п. Если такая сериализация не нужна, можно для конкретных структур/классов сделать специализацию определив внутри функции rawRead и rawWrite (см. тест, структура Preved). сериализатор ![]() ![]() import std.traits; // сериализация скалярных типов данных void serialize(S, D)(S stream, auto ref const D data) if(isScalarType!D) { stream.rawWrite(cast(const byte[])(&data)[0..1]); } // сериализация структур и классов void serialize(S, D)(S stream, auto ref const D data) if(isAggregateType!D) { // проверяем не определен ли член rawWrite static if(hasMember!(D, "rawWrite")) { data.rawWrite(stream); } else { // перебираем все члены структуры/класса foreach(ident; __traits(allMembers, D)) { // отсекаем функции, перечисления и прочую несериализуемую лабудень static if(is(typeof(mixin("D." ~ ident ~ ".offsetof")))) { mixin("serialize(stream, data." ~ ident ~ ");"); } } } } // сериализация массивов void serialize(S, D)(S stream, auto ref const D data) if(isArray!D) { // тип элемента alias E = typeof(data[0]); // сначала пишем длину serialize(stream, data.length); // если длина больше нуля, то пишем данные. if(data.length) { // если это массив скаляров, то пишем одним куском, иначе сериализуем поэлементно static if(isScalarType!E) { stream.rawWrite(cast(const byte[])data[]); } else { foreach(ref element; data) { serialize(stream, element); } } } } // десериализация, аналогично сериализации void deserialize(S, D)(S stream, ref D data) if(isScalarType!D) { stream.rawRead(cast(byte[])(&data)[0..1]); } void deserialize(S, D)(S stream, ref D data) if(isAggregateType!D) { static if(hasMember!(D, "rawRead")) { data.rawRead(stream); } else { foreach(ident; __traits(allMembers, D)) { static if(is(typeof(mixin("D." ~ ident ~ ".offsetof")))) { mixin("deserialize(stream, data." ~ ident ~ ");"); } } } } void deserialize(S, D)(S stream, ref D data) if(isArray!D) { alias E = typeof(data[0]); size_t length; deserialize(stream, length); if(length) { Unqual!E[] ndata; ndata.length = length; static if(isScalarType!E) { stream.rawRead(cast(byte[])ndata[]); } else { foreach(ref element; ndata) { deserialize(stream, element); } } data = cast(D) ndata; } } // функции-хелперы для сериализации/десериализации сразу нескольких значений void serialize(S, ARGS...)(S stream, auto ref const ARGS args) if(ARGS.length > 1) { foreach(ref arg; args) serialize(stream, arg); } void deserialize(S, ARGS...)(S stream, ref ARGS args) if(ARGS.length > 1) { foreach(ref arg; args) deserialize(stream, arg); } тест ![]() ![]() import std.stdio; import std.algorithm; import serializer; // примитивная структурв struct Foo { int fi; bool fb; string fs; } // класс с полем-структурой class Bar { int fi; bool fb; string fs; Foo ff; this(int i, bool b, string s, Foo f) { fi = i; fs = s; ff = f; } this() {} bool isSame(const Bar o) const { return fi == o.fi && fb == o.fb && fs == o.fs && ff == o.ff; } } // структура с переопределенными операциями сериализации/десериализации struct Preved { private string m_medved; void rawWrite(S)(S stream) const { stream.serialize("preved", m_medved); } void rawRead(S)(S stream) { string signature; stream.deserialize(signature); assert(signature == "preved"); stream.deserialize(m_medved); } } void main() { // готовим тестовые данные int s_int = 10; string s_string = "hello"; Foo s_foo = Foo(123, true, "foo"); Bar s_bar = new Bar(42, false, "bar", Foo(345, false, "foobar")); Foo[] s_foos = [ Foo(11, true, "foos1"), Foo(22, false, "foos2"), Foo(33, true, "foos3") ]; Preved s_preved = Preved("medved"); auto file = File("test.txt", "w"); // сериализуем в файл file.serialize(s_int, s_foo, s_string, s_bar, s_foos, s_preved); /******************************************************************/ // переменные для десериализации int d_int; string d_string; Foo d_foo; Bar d_bar = new Bar; Foo[] d_foos; Preved d_preved; file = File("test.txt", "rb"); // десериализуем из файла file.deserialize(d_int, d_foo, d_string, d_bar, d_foos, d_preved); // проверяем assert(d_int == s_int); assert(d_foo == s_foo); assert(d_string == s_string); assert(d_bar.isSame(s_bar)); assert(equal(d_foos, s_foos)); assert(d_preved == s_preved); } |
Сообщ.
#207
,
|
|
|
Ну, вот почему, почему всегда рефлексию показывают на этом тупом примере сериализации всех полей?
![]() |
Сообщ.
#208
,
|
|
|
Ну сериализатор его попросили написать. Если для составного типа не задана функция сериализации, то проход по полям лучше бинарной записи.
|
Сообщ.
#209
,
|
|
|
Цитата D_KEY @ Если для составного типа не задана функция сериализации, то он не сериализуем вообще fixed. Да и я спрашиваю вообще, а не про именно сейчас. |
Сообщ.
#210
,
|
|
|
Цитата MyNameIsIgor @ Цитата D_KEY @ Если для составного типа не задана функция сериализации, то он не сериализуем вообще fixed. Ну тебя же не смущает дефолтный конструктор копирования, например. Если все поля у объекта сериализуемы, то почему бы и не сериализовать, раз просят. |