Недавно я написал HTML-дезинфицирующее средство в Java. Он основан на смешанном подходе регулярных выражений и Java-коде. Лично я ненавижу регулярные выражения и его глупость (читаемость, ремонтопригодность и т. Д.), Но если вы уменьшите объем своих приложений, это может соответствовать вашим потребностям. Во всяком случае, мой дезинфицирующее средство использует белый список для тегов HTML и черный список для некоторых атрибутов стиля.
Для вашего удобства я создал игровое поле, чтобы вы могли проверить, соответствует ли код вашим требованиям: игровая площадка и код Java . Ваши отзывы будут оценены.
Существует небольшая статья, описывающая эту работу в моем блоге: http://roberto.open-lab.com
Сами фигурные скобки в порядке, все, что они делают, это ограничивают область действия, и вы ничего не замедлите. Его можно рассматривать как более чистый. (Всегда предпочитайте чистый код быстрому коду, если он чище, не беспокойтесь о скорости, пока не профилируете.)
Но в отношении ресурсов это плохая практика, потому что вы поставили себя в положение утечки ресурса. Если что-то в блоке бросает или возвращается, удар вы мертвы.
Используйте управление ресурсами с привязкой к области (SBRM, также известное как RAII), которое ограничивает ресурс областью, используя деструктор:
class mutex_lock
{
public:
mutex_lock(HANDLE pHandle) :
mHandle(pHandle)
{
//acquire resource
GetMutexLock(mHandle);
}
~mutex_lock()
{
// release resource, bound to scope
ReleaseMutexLock(mHandle);
}
private:
// resource
HANDLE mHandle;
// noncopyable
mutex_lock(const mutex_lock&);
mutex_lock& operator=(const mutex_lock&);
};
Итак, вы получите:
{
mutex_lock m(handle);
// brace brackets "scope" the lock,
// AUTOMATICALLY
}
Сделайте это, чтобы все ресурсы, это чище и безопаснее. Если вы в состоянии сказать: «Мне нужно освободить этот ресурс», вы сделали это неправильно; они должны обрабатываться автоматически.
Конкретное размещение {...}
в вашем исходном примере служит исключительно для форматирования сахара, делая его более очевидным, где начинается группа логически связанных операторов и где она заканчивается. Как показано в ваших примерах, это не влияет на скомпилированный код.
Я не знаю, что вы имеете в виду, говоря «это приводит к ошибке компилятора, если мьютекс не освобожден». Это просто неправда. Такое использование {...}
не может и не приведет к каким-либо ошибкам компилятора.
Является ли это хорошей практикой - дело личных предпочтений. Выглядит нормально. В качестве альтернативы вы можете использовать комментарии и / или отступы для обозначения логической группировки операторов в коде без каких-либо дополнительных {...}
.
Существуют различные методы, основанные на области видимости, некоторые из которых были проиллюстрированы другими ответами здесь, но то, что у вас есть в вашем OP, даже отдаленно не похоже на это. Еще раз, то, что у вас есть в OP (как показано), является чисто исходной привычкой форматирования с лишними {...}
, которые не влияют на сгенерированный код.
Все, что улучшает читаемость, IMHO, является хорошей практикой. Если добавление фигурных скобок улучшает читаемость, дерзайте!
Добавление дополнительных скобок не изменит способ компиляции кода. Это не замедлит работу программы.
Это намного полезнее (IMHO) в C ++ с деструкторами объектов; ваши примеры находятся на C.
Представьте, что вы создали класс MutexLock:
class MutexLock {
private:
HANDLE handle;
public:
MutexLock() : handle(0) {
GetMutexLock(handle);
}
~MutexLock() {
ReleaseMutexLock(handle);
}
}
Тогда вы могли бы ограничить эту блокировку только кодом, который в ней нуждался, предоставив новую область видимости с фигурными скобками:
{
MutexLock mtx; // Allocated on the stack in this new scope
// Use shared resource
}
// When this scope exits the destructor on mtx is called and the stack is popped
Если вы заключаете код в фигурные скобки, вам, вероятно, следует разбить его на отдельный метод. Если это один дискретный блок, почему бы не пометить его и не разделить по функциям? Это сделает явным то, что делает блок, и людям, которые позже прочитают код, не придется разбираться.
Фигурные скобки влияют на переменную область. Насколько я знаю, это все, что они делают.
Да, это может повлиять на то, как компилируется программа. Деструкторы будут вызываться в конце блока, а не ждать конца функции.
Часто это то, что вы хотите сделать. Например, ваши GetMutexLock и ReleaseMutexLock были бы намного лучше кода C++, написанного следующим образом:
struct MutexLocker {
Handle handle;
MutexLocker(handle) : handle(handle) { GetMutexLock(handle); }
~MutexLocker() { ReleaseMutexLock(handle); }
};
...
{
MutexLocker lock(handle);
// brace brackets "scope" the lock,
// must close block / remember
// to release the handle.
// similar to C#'s lock construct
}
Используя этот стиль C++, блокировка освобождается автоматически в конце блока. Он будет выпущен при любых обстоятельствах, включая исключения, за исключением setjmp/longjmp или сбоя или прерывания программы.
Это неплохая практика. Это не делает ничего медленнее; это просто способ структурирования кода.
Заставить компилятор выполнять проверку и принудительное выполнение ошибок за вас — это всегда хорошо!
Это не будет иметь никакого значения для скомпилированного кода, кроме вызова каких-либо деструкторов в конце этого блока, а не в конце окружающего блока, если только компилятор не является полностью безумным.
Лично я бы назвал это плохой практикой; Способ избежать ошибок, которые вы можете здесь совершить, заключается в использовании ограниченного управления ресурсами (иногда называемого RAII), а не в использовании типографских напоминаний, подверженных ошибкам. Я бы написал код как что-то вроде
{
mutex::scoped_lock lock(mutex);
// brace brackets *really* scope the lock
} // scoped_lock destructor releases the lock
{
gl_group gl(GL_TRIANGLES); // calls glBegin()
gl.Vertex3d( .. );
gl.Vertex3d( .. );
gl.Vertex3d( .. );
} // gl_group destructor calls glEnd()