При использовании языка с попыткой/уловком /, наконец, полезны инструкции D/s failure/success/exit scope? D, похоже, не может окончательно объяснить, почему эти утверждения используются в D. Но с таким языком, как C#, это полезно? Я разрабатываю язык, поэтому, если я увижу много профи, я его добавлю.Является ли D недостатком области/успеха/выхода?
ответ
scope(X)
не надо таким же образом, что for
не является необходимым, если Вы имеете if
и goto
.
Вот перефразировать пример из некоторого кода я пишу сегодня:
sqlite3* db;
sqlite3_open("some.db", &db);
scope(exit) sqlite3_close(db);
sqlite3_stmt* stmt;
sqlite3_prepare_v2(db, "SELECT * FROM foo;", &stmt);
scope(exit) sqlite3_finalize(stmt);
// Lots of stuff...
scope(failure) rollback_to(current_state);
make_changes_with(stmt);
// More stuff...
return;
Contrast это с помощью Try/уловом:
sqlite3* db;
sqlite3_open("some.db", &db);
try
{
sqlite3_stmt* stmt;
sqlite3_prepare_v2(db, "SELECT * FROM foo;", &stmt);
try
{
// Lots of stuff...
try
{
make_changes_with(stmt);
// More stuff...
}
catch(Exception e)
{
rollback_to(current_state);
throw;
}
}
finally
{
sqlite3_finalize(stmt);
}
}
finally
{
sqlite3_close(db);
}
код превратился в spaghetti, распространение ошибки восстановление по всему магазину и вытеснение уровня отступов для каждого блока try. Версия с использованием области (X), на мой взгляд, значительно читаема и понятна.
Золото не только потому, что вы должны мне, как это может стать спагетти, но и как код настолько специфичен для функции, что деструкторы должны/не могут быть решением. – 2009-08-08 20:23:54
Этот первый пример кода очень приятный. Это глоток свежего воздуха. Мы все так привыкли читать вторую переведенную форму, что первая выглядит странно, но она имеет ту же уверенность и прогрессию, что и код «раннего возвращения» или «раннего броска»: рассмотрим проблему A, укажите разрешение, забудьте о A и переходите к рассмотрению проблемы B, укажите разрешение, забудьте о B и двигайтесь дальше. – seh
try/catch/наконец заставляет уровень гнездования; Охранники не имеют. Кроме того, они позволяют вам писать код очистки в той же «области», что и код выделения, поэтому больше не нужно «открывать файл, прокручивать до конца функции, закрывать файл, прокручивать вверх до функции».
В принципе, это просто более удобное выражение обработки try/catch/finally - что-нибудь вы можете сделать с try/catch /, наконец, вы можете сделать с защитой области и наоборот.
Стоило ли? Я фанат D (так, предвзятый), но я бы сказал определенно.
Отличительная характеристика отказа - выход из успеха-выхода весьма полезен некоторое время - у меня нет реального опыта в мире с D, но инструкция Python with
также позволяет это, и я считаю это очень полезным, например, для совершить или отменить транзакцию БД, которая была открыта в защищенной части тела.
Когда я объяснил эту новую функцию Python (она уже давно существует ;-) для друзей и коллег, которые являются гуру на C++ и Java, я обнаружил, что они сразу поняли и увидели интерес к такой функции (У Python тоже есть finally
, но это не помогает отличить успех от отказа, как и на других языках [или C++ «RAII-уничтожение автоматических переменных в блочном эквиваленте»).
Я не понимаю. Я прочитал это http://effbot.org/zone/python-with-statement.htm Похоже, он позволяет запускать ctor и dtor. Не работает ли это без инструкции? Я не знаю питона хорошо или что на самом деле происходит – 2009-08-08 04:23:50
Точка в том, что специальный метод диспетчера контекста '__exit__' вызывается с информацией о том, какое исключение распространяется, если таковое имеется; таким образом, менеджер контекста для операций БД, например, может различать случаи успеха, гарантируя фиксацию БД и отказы, требующие откат БД. Вы говорите о совершенно другой проблеме: dtors, как таковой, может быть запущен в попытке /, наконец, просто синтаксически неуклюже, чем RAII (смотрите THAT up! -), но функционально эквивалентны. Но отличать успех от неудачи, в некоторых случаях, CRUCIAL! –
Отказ от ответственности Я тоже фанат-фанат.
someRiskyFunctionThatMayThrow();
lock();
/* we have definitly got the lock so lets active
a piece of code for exit */
scope(exit)
freelock();
По сравнению с:
try
{
someRiskyFunctionThatMayThrow();
lock();
}
finally
{
freeLockIfNotGot();
}
@DK, Следует отметить, в C++ (и Java я думаю) вы можете легко использовать «анонимный» класс, чтобы выполнить то же самое, Scope (выход):
int some_func()
{
class _dbguard { sqlite3* db;
_dbguard(const _dbguard&); _dbguard& operator=(const _dbguard&);
public:
_dbguard(const char* dbname) { sqlite3_open(dbname, &db);}
~_dbguard() {sqlite3_close(db);}
operator sqlite3*() { return db; }
} db("dbname");
...
}
И если вы сделали это более одного раза, сразу же превратив его в полноценный класс, чтобы обрабатывать RAII для вас. Это так просто писать, я не могу представить себе программу на C++, которая использует sqlite (как используется в примере) без создания таких классов, как CSqlite_DB и CSqlite_Stmt.На самом деле оператор sqlite3 *() должен быть anathama и полная версия будет просто методы, которые обеспечивают операторы:
class CSqlite3_DB {
...
CSqlite3_Stmt Prepare(const std::string& sql) {
sqlite3_stmt* stmt = 0;
try {
sqlite3_prepare_v2(db, sql.c_str(), &stmt);
} catch (...) {}
return stmt;
}
};
Что касается первоначального вопроса, я бы сказал, что ответ «не очень». Надлежащее уважение к DRY скажет вам взять эти длинные блоки try/catch/finally и преобразовать их в отдельные классы, которые скрывают части try/catch от остальной части, где они могут (в случае масштаба (сбоя)), и делают управление ресурсами прозрачно (в случае области (выход)).
отличный ответ. – 2010-06-21 18:45:54
... хотя я укажу, объем (выход) составляет около 200 символов меньше, чем любая из версий :-) –
На самом деле, поскольку я пишу это, я предпочитаю метод D. Когда я действительно думал о масштабе (неудаче) и объеме (успехе), я был продан. Способ RAII не может дублировать эти функции без уродливой поддержки MACRO. Тем не менее, для примера SqlLite полный класс оболочки C++ является «правильным» решением на C++. – jmucchiello
Следует отметить, что для C++ доступны также область действия (сбой), область действия (сбой) и область (успех).
- Для области (выхода) есть библиотека Boost.ScopeExit.
- Для области (сбоя) и объема (успеха) есть библиотека stack_unwinding.
следующий синтаксис поддерживается, случай 1:
try
{
int some_var=1;
cout << "Case #1: stack unwinding" << endl;
scope(exit)
{
cout << "exit " << some_var << endl;
++some_var;
};
scope(failure)
{
cout << "failure " << some_var << endl;
++some_var;
};
scope(success)
{
cout << "success " << some_var << endl;
++some_var;
};
throw 1;
} catch(int){}
печатает:
Case #1: stack unwinding
failure 1
exit 2
Случай 2:
{
int some_var=1;
cout << "Case #2: normal exit" << endl;
scope(exit)
{
cout << "exit " << some_var << endl;
++some_var;
};
scope(failure)
{
cout << "failure " << some_var << endl;
++some_var;
};
scope(success)
{
cout << "success " << some_var << endl;
++some_var;
};
}
печатает:
Case #2: normal exit
success 1
exit 2
wtf столько кода !? Я реализовал SCOPE_EXIT, SCOPE_SUCCESS и SCOPE_FAIL в 6 строках кода C++ 11. Все, что я делаю, - это функция лямбда. Но +1 в любом случае. Ни в коем случае я не включаю те заголовки tho. Очень перебор.Heres 3 lines, другие 3 - marco defs, специфичные для моего кода http://pastebin.com/zaLZ6fP7 – 2012-10-21 04:28:02
@ acidzombie24: 1. Ваше решение не работает должным образом, проверьте это: http://ideone.com/IcWMEf никаких исключений внутри ~ Test(), но печатается «сбой». –
@ acidzombie24: 2. Для C++ 11-единственное решение на самом деле короче. Но эта библиотека хорошо работает и для C++ 98/C++ 03. Большая часть кода связана с эмуляцией «lambdas» для C++ 98/C++ 03. –
- 1. Является ли это недостатком дизайна?
- 2. Является ли D статически скомпилированным?
- 3. , что является недостатком <! DOCTYPE HTML>
- 4. Что является недостатком замены size_t unsigned long
- 5. Является ли Java-совместимость с Scala не недостатком?
- 6. Является ли это недостатком реализации Groovy шаблона Singleton?
- 7. Является ли подчеркивание в литералах в java выгодным или недостатком?
- 8. Является ли это плохой настройкой Moq или недостатком Moq?
- 9. Является ли недостатком безопасности для запуска нового процесса на сервере?
- 10. Является ли это недостатком в прототипной модели наследования JavaScript?
- 11. Является ли% d a cast in C?
- 12. Является ли точная компоновка D структур определена?
- 13. Является ли это шаблон особенным выражением: "/ d $ /" ...?
- 14. Что является недостатком при использовании websocket на мобильном устройстве?
- 15. Что является недостатком структурирования таблиц SQL таким образом?
- 16. Android-что является недостатком использования статического объекта пользовательского интерфейса
- 17. Двоичный поиск C++ (что является недостатком в этом коде)
- 18. Что является недостатком использования объекта .__ new__ в __new__?
- 19. Что является недостатком отсутствия файла index.html в некоторых каталогах
- 20. Что является недостатком обновления ARM TTBR (Translate Table Base Register)?
- 21. Что является недостатком использования функциональной расширяемости в COQ
- 22. Почему это не является огромным недостатком в шифровании?
- 23. Не избыточно ли \ d в [\ w \ d]?
- 24. Является ли это недостатком для прямого поиска Ajax или проблемы с сервером
- 25. не может получить доступ к методу подкласса, является ли это недостатком Generics? или я что-то
- 26. Как вы узнаете, является ли это веб-сервером/недостатком кода/vm
- 27. Должен ли я использовать статические классы и что является преимуществом (или недостатком)?
- 28. Есть ли разница между \ d и \ d +?
- 29. Является ли действие варианта -D в Maven временным или нет?
- 30. Является ли набор принципов SOLID отсутствием дополнительного «D»?
У вас есть блог или какой-либо сайт? –
Ctrl Alt D-1337: Нет. Вы должны сообщить мне (мой адрес электронной почты в моем профиле). Я могу опубликовать его под другим именем. (У меня разные имена пользователей для разных интересов) – 2009-08-08 20:30:06
D наконец-то – BCS