你什么时候在 C/C++/C# 等中使用代码块?我知道它们背后的理论原因,但是你什么时候在实际程序中使用它们呢?
编辑:我刚刚意识到我在switch
语句中使用它们,否则变量将在同一范围内(grr 用于类似的东西i
):
switch (x) { case "abc": { /* code */ } break; }
等(为了澄清,在 switch 语句中,不需要额外的大括号。)
有关的:
你什么时候在 C/C++/C# 等中使用代码块?我知道它们背后的理论原因,但是你什么时候在实际程序中使用它们呢?
编辑:我刚刚意识到我在switch
语句中使用它们,否则变量将在同一范围内(grr 用于类似的东西i
):
switch (x) { case "abc": { /* code */ } break; }
等(为了澄清,在 switch 语句中,不需要额外的大括号。)
有关的:
I sometimes, but rarely, use naked code blocks to limit scope. For example, take the following code:
double bedroomTemperature = ReadTemperature(Room.Bedroom);
database.Store(Room.Bedroom, bedroomTemperature);
double bathroomTemperature = ReadTemperature(Room.Bathroom);
database.Store(Room.Bedroom, bedroomTemperature);
The code looks fine at first glance, but contains a subtle copy-pasta error. In the database we have stored the bedroom temperature for both readings. If it had been written as:
{
double bedroomTemperature = ReadTemperature(Room.Bedroom);
database.Store(Room.Bedroom, bedroomTemperature);
}
{
double bathroomTemperature = ReadTemperature(Room.Bathroom);
database.Store(Room.Bedroom, bedroomTemperature);
}
Then the compiler (or even IDE if it is intelligent enough) would have spotted this.
However, 90% of the time the code can be refactored to make the naked blocks unnecessary, e.g. the above code would be better written as a loop or two calls to a method that reads and stores the temperature:
foreach (Room room in [] { Room.Bedroom, Room.Bathroom })
{
double temperature = ReadTemperature(room);
database.Store(room, temperature);
}
Naked blocks are useful on occasion though.
我对开关块做同样的事情,即使它不是必需的。一般来说,我使用代码块,它们要么使代码更具可读性(无论是通过为相似的代码块提供相似的外观还是仅仅获得缩进),或者它们正确地作用域变量。
finally
您可以通过使用代码块和 RAII 对象在 C++中获得类似的行为。
{
std::fstream f(filename)
...
}
无论是什么导致我们离开块,都会在析构函数中释放文件描述符。
(就我个人而言,我仍在努力实践这一点。我的 c 根牢牢地抓住了我的习惯......)
除了显而易见的(“当语法需要时”,例如在 switch 或 try catch finally 中)之外,
每当您需要将 2 个或更多语句的块视为一个原子单元时