您是否使用花括号进行额外的范围界定?[关闭]

IT小君   2021-10-19T07:46:59

我的意思是除了在函数、类、if、while、switch、try-catch 需要时使用它。

在我看到这个 SO question 之前,我不知道可以这样做

在上面的链接中,Eli 提到“他们使用它在逻辑部分折叠他们的代码,这些逻辑部分不属于通常会折叠的函数、类、循环等。”

除了上面提到的还有哪些用途?

使用花括号来限制变量的范围并仅在需要时扩展范围(在“需要访问”的基础上工作)是个好主意吗?或者它实际上是愚蠢的?

如何使用作用域,以便您可以在不同作用域但在同一个更大的作用域中使用相同的变量名称?或者重用相同的变量(如果您想使用相同的变量名)并节省释放和分配(我认为某些编译器可以对此进行优化?)是更好的做法吗?还是完全使用不同的变量名更好?

评论(13)
IT小君

如果我使用的是我想在特定时间释放的资源,我会这样做,例如:

void myfunction()
{
  {
  // Open serial port
     SerialPort port("COM1", 9600);
     port.doTransfer(data);
  } // Serial port gets closed here.

  for(int i = 0; i < data.size(); i++)
     doProcessData(data[i]);
  etc...
}
2021-10-19T07:46:59   回复
IT小君

出于几个原因,我不会为此目的使用花括号。

  1. 如果您的特定功能足够大,您需要执行各种范围界定技巧,也许可以将该功能分解为更小的子功能。

  2. 为作用域引入大括号以重用变量名只会导致代码混乱和麻烦。

只是我的 2 美分,但我在其他最佳实践材料中看到了很多这类东西。

2021-10-19T07:46:59   回复
IT小君

C++

有时您需要引入一个额外的大括号级别的范围来重用变量名,因为这样做是有意义的:

switch (x) {
    case 0:
        int i = 0;
        foo(i);
        break;
    case 1:
        int i = 1;
        bar(i);
        break;
}

上面的代码不能编译。你需要做到:

switch (x) {
    case 0:
        {
            int i = 0;
            foo(i);
        }
        break;
    case 1:
        {
            int i = 1;
            bar(i);
        }
        break;
}
2021-10-19T07:47:00   回复
IT小君

我经常使用的最常见的“非标准”作用域使用是使用作用域互斥锁。

void MyClass::Somefun()
{
    //do some stuff
    {
        // example imlementation that has a mutex passed into a lock object:
        scopedMutex lockObject(m_mutex); 

        // protected code here

    } // mutex is unlocked here
    // more code here
}

这有很多好处,但最重要的是,即使在受保护的代码中抛出异常,锁也会始终被清除。

2021-10-19T07:47:00   回复
IT小君

正如其他人所说,最常见的用途是确保析构函数在您想要的时候运行。使特定于平台的代码更清晰一点也很方便:

#if defined( UNIX )
    if( some unix-specific condition )
#endif
    {
        // This code should always run on Windows but 
        // only if the above condition holds on unix
    }

为 Windows 构建的代码看不到 if,只有大括号。这比:

#if defined( UNIX )
    if( some unix-specific condition ) {
#endif
        // This code should always run on Windows but 
        // only if the above condition holds on unix
#if defined( UNIX )
    }
#endif
2021-10-19T07:47:00   回复
IT小君

它可以是代码生成器的福音。假设您有一个嵌入式 SQL (ESQL) 编译器;它可能希望将 SQL 语句转换为需要局部变量的代码块。通过使用块,它可以反复重用固定的变量名称,而不必创建具有单独名称的所有变量。当然,这并不太难,但这比必要的要难。

2021-10-19T07:47:00   回复
IT小君

正如其他人所说,由于全能的 RAII(资源获取即初始化)习惯用法/模式,这在 C++ 中相当普遍。

对于 Java 程序员(也许 C#,我不知道)这将是一个陌生的概念,因为基于堆的对象和 GC 会杀死 RAII。恕我直言,能够将对象放在堆栈上是 C++ 相对于 Java 的最大单一优势,并且使编写良好的 C++ 代码比编​​写良好的 Java 代码更清晰。

2021-10-19T07:47:00   回复
IT小君

我只在需要通过 RAII 释放某些东西时才使用它,即使如此,也只有在应该尽可能早地释放它时才使用它(例如释放锁)。

2021-10-19T07:47:01   回复
IT小君

用 Java 编程 我经常想限制一个方法的范围,但我从来没有想过要使用标签。由于我在将标签用作中断目标时大写我的标签,因此在这些场合使用像您建议的混合大小写标记块正是我想要的。

通常,代码块太短而无法分解成一个小方法,而且通常是框架方法中的代码(如启动()或关闭()),实际上最好将代码放在一个方法中。

我个人讨厌普通的浮动/悬垂大括号(尽管这是因为我们是严格的横幅样式缩进商店),并且我讨厌评论标记:

// yuk!
some code
{
scoped code
}
more code

// also yuk!
some code
/* do xyz */ {
    scoped code
    }
some more code

// this I like
some code
DoXyz: {
    scoped code
    }
some more code

我们考虑使用“if(true) {”,因为 Java 规范明确指出这些将在编译时优化(if(false) 的全部内容也是如此——这是一个调试功能),但我在少数地方讨厌这样我尝试过这个。

所以我认为你的想法很好,一点也不傻。我一直认为我是唯一一个想做这件事的人。

2021-10-19T07:47:01   回复
IT小君

是的,我使用这种技术是因为 RAII。我也在普通C 中使用这种技术,因为它使变量更紧密地结合在一起。当然,我应该考虑更多地分解功能。

我做的一件事可能在风格上有争议,就是将左花括号放在声明的行上或在其上添加注释。我想减少浪费的垂直空间。这是基于 Google C++ 风格指南推荐的。.

/// c++ code
/// references to boost::test
BOOST_TEST_CASE( curly_brace )
{
  // init
  MyClass instance_to_test( "initial", TestCase::STUFF ); {
    instance_to_test.permutate(42u);
    instance_to_test.rotate_left_face();
    instance_to_test.top_gun();
  }
  { // test check
    const uint8_t kEXP_FAP_BOOST = 240u;
    BOOST_CHECK_EQUAL( instance_to_test.get_fap_boost(), kEXP_FAP_BOOST);
  }
}
2021-10-19T07:47:01   回复
IT小君

我同意 agartzke。如果您觉得需要对较大的逻辑代码块进行分段以提高可读性,则应考虑重构以清理繁忙和杂乱的成员。

2021-10-19T07:47:01   回复
IT小君

它有它的位置,但我不认为这样做是为了让 $foo在同一函数或其他(逻辑,而不是词法)范围内在这里是一个变量而那里是一个不同的变量是一个好主意。尽管编译器可能完全理解这一点,但对于试图阅读代码的人来说,这似乎太难了。

2021-10-19T07:47:02   回复
IT小君

我工作的公司有一个静态分析策略,将局部变量声明保留在函数的开头附近。很多时候,用法是在函数的第一行之后很多行,所以我无法在屏幕上同时看到声明和第一个引用。我为“规避”该政策所做的工作是将声明保持在引用附近,但通过使用花括号提供额外的范围。但是它增加了缩进,有些人可能会争辩说它使代码更丑。

2021-10-19T07:47:03   回复