有用的替代控制结构?

发布于 2024-10-04 22:52:50 字数 863 浏览 9 评论 0原文

有时,当我编程时,我发现某些特定的控制结构对我非常有用,但在我的编程语言中不能直接使用。我认为我最常见的愿望是像“split while”(我不知道实际上该怎么称呼它):

{
    foo();
} split_while( condition ) {
    bar();
}

这段代码的语义是 foo() 总是运行,然后检查条件。如果为 true,则运行 bar() 并返回到第一个块(从而再次运行 foo() 等)。感谢 reddit 用户 zxqdms 的评论,我了解到Donald E. Knuth 在他的论文 “使用结构化编程go to 语句”(参见第 279 页)。

您认为哪些替代控制结构是组织计算的有用方法?

我的目标是为我自己和其他人提供思考结构化代码的新方法,以改进分块和推理。

注意:我不是问如何概括所有可能的控制结构,无论是使用jneif /goto、Lisp 宏、延续、单子、组合子、夸克或其他任何东西。我问什么专业化在描述代码时有用。

Sometimes when I am programming, I find that some particular control structure would be very useful to me, but is not directly available in my programming language. I think my most common desire is something like a "split while" (I have no idea what to actually call this):

{
    foo();
} split_while( condition ) {
    bar();
}

The semantics of this code would be that foo() is always run, and then the condition is checked. If true, then bar() is run and we go back to the first block (thus running foo() again, etc). Thanks to a comment by reddit user zxqdms, I have learned that Donald E. Knuth writes about this structure in his paper "Structured programming with go to statements" (see page 279).

What alternative control structures do you think are a useful way of organizing computation?

My goal here is to give myself and others new ways of thinking about structuring code, in order to improve chunking and reasoning.

Note: I'm not asking about how to generalize all possible control structures, whether by using jne, if/goto, Lisp macros, continuations, monads, combinators, quarks, or whatever else. I'm asking what specializations are useful in describing code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(28

挽你眉间 2024-10-11 22:52:51

如果您主要使用非函数式语言,那么 Python 中的生成器确实很新颖。更一般地说:延续、协同例程、惰性列表。

Generators, in Python, are genuinely novel if you've mostly worked with non-functional languages. More generally: continuations, co-routines, lazy lists.

情未る 2024-10-11 22:52:51

这可能不算数,但在 Python 中,我很沮丧没有 do 循环。

安托确保我这个答案不会得到赞成票,我会对我在任何时间段内使用的任何缺乏 goto 的语言感到恼火。

This probably doesn't count, but in Python, I was upset there was no do loop.

Anto ensure I get no upvotes for this answer, I wind up annoyed at any language I work in for any period of time that lacks goto's.

难忘№最初的完美 2024-10-11 22:52:51
for int i := 0 [down]to UpperBound() [step 2]

每个 C 派生语言中都缺失。

在投票或发表评论之前请考虑
这对于 for (int i = 0; i <= UpperBound(); i++) 来说并不是多余的,它具有不同的语义:

  1. UpperBound() 被评估仅一次

  2. 该情况 UpperBound() == MAX_INT 不会产生无限循环

for int i := 0 [down]to UpperBound() [step 2]

Missing in every C-derived language.

Please consider before you vote or write a comment:
This is not redundant to for (int i = 0; i <= UpperBound(); i++), it has different semantics:

  1. UpperBound() is evaluated only once

  2. The case UpperBound() == MAX_INT does not produce an infinite loop

音栖息无 2024-10-11 22:52:51

这与 @Paul Keister 的回复类似。

(咕哝,咕哝)几年前,我正在开发的应用程序有很多所谓的控制中断处理的变体——所有这些逻辑都将排序的数据行分成带有页眉和页脚的组和子组。由于应用程序是用 LISP 编写的,因此我们在名为“WITH-CONTROL-BREAKS”的宏中捕获了常见的习惯用法。如果我将该语法转换为流行的波浪线形式,它可能看起来像这样:

withControlBreaks (x, y, z : readSortedRecords()) {
  first (x) :     { emitHeader(x); subcount = 0; }
  first (x, y) :  { emitSubheader(x, y); zTotal = 0; }
  all (x, y, z) : { emitDetail(x, y, z); ztotal += z; }
  last (x, y) :   { emitSubfooter(x, y, zTotal); ++subCount; }
  last (x) :      { emitFooter(x, subcount); }
}

在这个现代时代,随着 SQL、XQuery、LINQ 等的广泛使用,这种需求似乎并不像它所使用的那样出现。到。但有时,我希望我手头有这样的控制结构。

This is similar to the response by @Paul Keister.

(mumble, mumble) years ago, the application I was working on had lots of variations of so-called control-break processing -- all that logic that goes into breaking sorted rows of data into groups and subgroups with headers and footers. As the application was written in LISP, we had captured the common idioms in a macro called WITH-CONTROL-BREAKS. If I were to transpose that syntax into the ever-popular squiggly form, it might look something like this:

withControlBreaks (x, y, z : readSortedRecords()) {
  first (x) :     { emitHeader(x); subcount = 0; }
  first (x, y) :  { emitSubheader(x, y); zTotal = 0; }
  all (x, y, z) : { emitDetail(x, y, z); ztotal += z; }
  last (x, y) :   { emitSubfooter(x, y, zTotal); ++subCount; }
  last (x) :      { emitFooter(x, subcount); }
}

In this modern era, with widespread SQL, XQuery, LINQ and so on, this need does not seem to arise as much as it used to. But from time to time, I wish that I had that control structure at hand.

少女净妖师 2024-10-11 22:52:51
foo();

while(condition)
{
   bar();
   foo();
}
foo();

while(condition)
{
   bar();
   foo();
}
半岛未凉 2024-10-11 22:52:51

PL/I 风格的“for”循环范围怎么样? VB 的等价物是:

' Counts 1, 2, ... 49, 50, 23, 999, 998, ..., 991, 990
  For I = 1 to 50, 23, 999 to 990 Step -1

我能看到的最常见用法是对索引列表运行一个循环,然后再放入一个。顺便说一句,For-Each 用法也很方便:

' Bar1, Bar2, Bar3 are an IEnum(Wazoo); Boz is a Wazoo
  For Each Foo as Wazoo in Bar1, Bar2, Enumerable.One(Boz), Bar3

这将对 Bar1 中的所有项目、Bar2、Boz 和 Bar3 中的所有项目运行循环。 Linq 可能会在没有太大困难的情况下允许这样做,但内在语言支持可能会更有效一些。

How about PL/I style "for" loop ranges? The VB equivalent would be:

' Counts 1, 2, ... 49, 50, 23, 999, 998, ..., 991, 990
  For I = 1 to 50, 23, 999 to 990 Step -1

The most common usage I can see would be to have a loop run for a list of indices, and then throw in one more. BTW, a For-Each usage could also be handy:

' Bar1, Bar2, Bar3 are an IEnum(Wazoo); Boz is a Wazoo
  For Each Foo as Wazoo in Bar1, Bar2, Enumerable.One(Boz), Bar3

This would run the loop on all items in Bar1, all items in Bar2, Boz, and Bar3. Linq would probably allow this without too much difficulty, but intrinsic language support might be a little more efficient.

北方的巷 2024-10-11 22:52:51

case-in 类型结构是许多语言中不可用的控制结构之一。与开关类型结构类似,它允许您拥有一个格式整齐的可能选项列表,但匹配第一个正确的选项(而不是第一个与输入匹配的选项)。这样的 LISP(确实有):

(cond
   ((evenp a) a)        ;if a is even return a
   ((> a 7) (/ a 2))    ;else if a is bigger than 7 return a/2
   ((< a 5) (- a 1))    ;else if a is smaller than 5 return a-1
   (t 17))              ;else return 17

或者,对于那些更喜欢 C 语言格式的人来说,

cond 
    (a % 2 == 0): 
        a;     break;
    (a > 7):
        a / 2; break;
    (a < 5):
        a - 1; break;
    default:
        17;    break;

它基本上是 if/elseif/elseif/else 结构的更准确的表示,而不是switch 是,并且它可以非常方便地以干净、可读的方式表达该逻辑。

One of the control structures that isn't available in many languages is the case-in type structure. Similar to a switch type structure, it allows you to have a neatly formatted list of possible options, but matches the first one that's true (rather then the first one that matches the input). A LISP of such such (which does have it):

(cond
   ((evenp a) a)        ;if a is even return a
   ((> a 7) (/ a 2))    ;else if a is bigger than 7 return a/2
   ((< a 5) (- a 1))    ;else if a is smaller than 5 return a-1
   (t 17))              ;else return 17

Or, for those that would prefer a more C-like format

cond 
    (a % 2 == 0): 
        a;     break;
    (a > 7):
        a / 2; break;
    (a < 5):
        a - 1; break;
    default:
        17;    break;

It's basically a more accurate representation of the if/elseif/elseif/else construct than a switch is, and it can come in extremely handing in expressing that logic in a clean, readable way.

方觉久 2024-10-11 22:52:51

使用移动窗口(n 个元素而不是 1 个)遍历列表怎么样?
我认为,这与@munificent的答案有切线关系。

像 It这样的东西

#python
#sum of adjacent elements
for x,y in pairs(list):
    print x + y

def pairs(l):              
    i=0                    
    while i < len(l)-1:    
        yield (l[i],l[i+1])
        i+=1               

对于某些类型的事情很有用。不要误会我的意思,这很容易作为函数实现,但我认为很多人在有更具体的情况时尝试引入 forwhile 循环/工作的描述性工具。

How about iterating with a moving window (of n elements instead of 1) through a list?
This is tangentially related @munificent's answer, I think.

Something like

#python
#sum of adjacent elements
for x,y in pairs(list):
    print x + y

def pairs(l):              
    i=0                    
    while i < len(l)-1:    
        yield (l[i],l[i+1])
        i+=1               

It is useful for certain types of things. Don't get me wrong, this is easy to implement as a function, but I think a lot of people try to bring out for and while loops when there are more specific/descriptive tools for the job.

↘人皮目录ツ 2024-10-11 22:52:50

相当常见的一种是无限循环。我想这样写:

forever {
  // ...
}

One that's fairly common is the infinite loop. I'd like to write it like this:

forever {
  // ...
}
时光无声 2024-10-11 22:52:50

有时,我需要一个带有索引的 foreach 循环。可以这样写:(

foreach (index i) (var item in list) {
  // ...
}

我不是特别喜欢这种语法,但你明白了)

Sometimes, I need to have a foreach loop with an index. It could be written like this:

foreach (index i) (var item in list) {
  // ...
}

(I'm not particularly fond of this syntax, but you get the idea)

豆芽 2024-10-11 22:52:50

大多数语言都有内置函数来涵盖常见情况,但“fencepost”循环始终是一件苦差事:您希望在每次迭代中执行某些操作并在迭代之间执行其他操作的循环。例如,用分隔符连接字符串:

string result = "";
for (int i = 0; i < items.Count; i++) {
    result += items[i];
    if (i < items.Count - 1) result += ", "; // This is gross.
    // What if I can't access items by index?
    // I have off-by-one errors *every* time I do this.
}

我知道折叠可以覆盖这种情况,但有时您需要一些命令式的东西。如果你能做到的话那就太酷了:

string result = "";
foreach (var item in items) {
    result += item;
} between {
    result += ", ";
}

Most languages have built-in functions to cover the common cases, but "fencepost" loops are always a chore: loops where you want to do something on each iteration and also do something else between iterations. For example, joining strings with a separator:

string result = "";
for (int i = 0; i < items.Count; i++) {
    result += items[i];
    if (i < items.Count - 1) result += ", "; // This is gross.
    // What if I can't access items by index?
    // I have off-by-one errors *every* time I do this.
}

I know folds can cover this case, but sometimes you want something imperative. It would be cool if you could do:

string result = "";
foreach (var item in items) {
    result += item;
} between {
    result += ", ";
}
壹場煙雨 2024-10-11 22:52:50

与 else 循环:

while (condition) {
  // ...
}
else {
  // the else runs if the loop didn't run
}

Loop with else:

while (condition) {
  // ...
}
else {
  // the else runs if the loop didn't run
}
像极了他 2024-10-11 22:52:50
{
    foo();
} split_while( condition ) {
    bar();
}

您可以使用常规 while 轻松完成此操作:

while (true) {
    foo();
    if (!condition) break;
    bar();
}

现在我已经克服了对 break 的非理性厌恶,我经常这样做。

{
    foo();
} split_while( condition ) {
    bar();
}

You can accomplish that pretty easily using a regular while:

while (true) {
    foo();
    if (!condition) break;
    bar();
}

I do that pretty frequently now that I got over my irrational distaste for break.

他不在意 2024-10-11 22:52:50

如果你看看 Haskell,虽然各种控制结构都有特殊的语法,但控制流通常是由类型捕获的。最常见的此类控制类型是 Monad、Arrows 和 applicative functor。因此,如果您想要一种特殊类型的控制流,它通常是某种高阶函数,您可以自己编写它,也可以在非常大的 Haskells 包数据库(Hackage)中找到一个。

此类函数通常位于 Control 命名空间中,您可以在其中找到用于并行执行到错误处理的模块。过程语言中常见的许多控制结构在 Control.Monad 中都有对应的函数,其中包括循环和 if 语句。 if-else 是 haskell 中的关键字表达式,如果没有 else 在表达式中没有意义,但在 monad 中则完全有意义,因此没有 else 的 if 语句被函数 when 捕获和除非

另一个常见的情况是在更一般的上下文中进行列表操作。函数式语言非常喜欢fold,以及像mapfilter这样的专业版本。如果你有一个 monad,那么它就有一个 fold 的自然扩展。这称为 foldM,因此还有您能想到的任何专门版本的 Fold 的扩展,例如 mapMfilterM

If you look at Haskell, although there is special syntax for various control structures, control flow is often captured by types. The most common kind of such control types are Monads, Arrows and applicative functors. So if you want a special type of control flow, it's usually some kind of higher-order function and either you can write it yourself or find one in Haskells package database (Hackage) wich is quite big.

Such functions are usually in the Control namespace where you can find modules for parallel execution to errorhandling. Many of the control structures usually found in procedural languages have a function counterpart in Control.Monad, among these are loops and if statements. If-else is a keyworded expression in haskell, if without an else doesn't make sense in an expression, but perfect sense in a monad, so the if statements without an else is captured by the functions when and unless.

Another common case is doing list operation in a more general context. Functional languages are quite fond of fold, and the Specialized versions like map and filter. If you have a monad then there is a natural extension of fold to it. This is called foldM, and therefor there are also extensions of any specialized version of fold you can think of, like mapM and filterM.

同展鸳鸯锦 2024-10-11 22:52:50

对于(lisp 风格)宏、尾部调用和延续,所有这些都很奇怪。

使用宏,如果标准控制流结构不足以满足给定的应用程序,程序员可以编写自己的控制流结构(以及更多)。它只需要一个简单的宏来实现您作为示例给出的结构。

通过尾部调用,我们可以将复杂的控制流模式(例如实现状态机)分解为函数。

延续是一个强大的控制流原语(try/catch 是它们的受限版本)。与尾部调用和宏相结合,复杂的控制流模式(回溯、解析等)变得简单。此外,它们在网络编程中很有用,因为使用它们您可以反转控制反转;你可以有一个函数,要求用户提供一些输入,进行一些处理,要求用户提供更多输入,等等。

为了解释Scheme标准,你应该设法消除使其他功能似乎是必要的。

With (lisp-style) macros, tail-calls, and continuations all of this is quaint.

With macros, if the standard control flow constructs are not sufficient for a given application, the programmer can write their own (and so much more). It would only require a simple macro to implement the constructs you gave as an example.

With tail-calls, one can factor out complex control flow patters (such as implementing a state machine) into functions.

Continuations are a powerful control flow primitive (try/catch are a restricted version of them). Combined with tail-calls and macros, complex control flow patterns (backtracking, parsing, etc.) become straight-forward. In addition, they are useful in web programming as with them you can invert the inversion of control; you can have a function that asks the user for some input, do some processing, asks the user for more input, etc.

To paraphrase the Scheme standard, instead of piling more features onto your language, you should seek to remove the limitations that make the other features appear necessary.

云仙小弟 2024-10-11 22:52:50

这只是一个一般的想法和语法:

if (cond)
   //do something
else (cond)
   //do something
also (cond)
   //do something
else
   //do something
end

ALSO 条件总是被评估。 ELSE 照常工作。

它也适用于案例。也许这是消除break语句的好方法:

case (exp)
   also (const)
      //do something
   else (const)
      //do something
   also (const)
      //do something
   else
      //do something
end

可以理解为:

switch (exp)
   case (const)
      //do something
   case (const)
      //do something
      break
   case (const)
      //do something
   default
      //do something
end

我不知道这是否有用或易于阅读,但它是一个例子。

This is just a general idea and syntax:

if (cond)
   //do something
else (cond)
   //do something
also (cond)
   //do something
else
   //do something
end

ALSO condition is always evaluated. ELSE works as usual.

It works for case too. Probably it is a good way to eliminate break statement:

case (exp)
   also (const)
      //do something
   else (const)
      //do something
   also (const)
      //do something
   else
      //do something
end

can be read as:

switch (exp)
   case (const)
      //do something
   case (const)
      //do something
      break
   case (const)
      //do something
   default
      //do something
end

I don't know if this is useful or simple to read but it's an example.

回心转意 2024-10-11 22:52:50

如果不是:

unless (condition) {
  // ...
}

而不是:

until (condition) {
  // ...
}

if not:

unless (condition) {
  // ...
}

while not:

until (condition) {
  // ...
}
揽清风入怀 2024-10-11 22:52:50

我发现自己有时在主流语言中缺少带标签的循环。例如,

int i, j;
for outer ( i = 0; i < M; ++i )
    for ( j = 0; j < N; ++j )
        if ( l1[ i ] == l2[ j ] )
           break outer;

是的,我通常可以使用 goto 来模拟这一点,但是 continue 的等效项将要求您将增量移动到标签之后的循环体末尾,这会造成伤害可读性。您还可以通过在内循环中设置一个标志并在外循环的每次迭代时检查它来完成此操作,但它总是看起来很笨拙。

(奖励:我有时希望有一个 redocontinuebreak 一起使用。它将返回到循环的开头而不评估增量。)

Labeled loops are something I find myself missing sometimes from mainstream languages. e.g.,

int i, j;
for outer ( i = 0; i < M; ++i )
    for ( j = 0; j < N; ++j )
        if ( l1[ i ] == l2[ j ] )
           break outer;

Yes, I can usually simulate this with a goto, but an equivalent for continue would require you to move the increment to the end of loop body after the label, hurting the readability. You can also do this by setting a flag in the inner loop and checking it at each iteration of the outer loop, but it always looks clumsy.

(Bonus: I'd sometimes like to have a redo to go along with continue and break. It would return to the start of the loop without evaluating the increment.)

冬天的雪花 2024-10-11 22:52:50

我建议使用“then”运算符。它在第一次迭代中返回左操作数,在所有其他迭代中返回右操作数:

var result = "";
foreach (var item in items) {
    result += "" then ", ";
    result += item;
}

在第一次迭代中,它在结果中添加“”,在所有其他迭代中,它添加“,”,因此您会得到一个包含用逗号分隔的每个项目的字符串。

I propose the "then" operator. It returns the left operand on the first iteration and the right operand on all other iterations:

var result = "";
foreach (var item in items) {
    result += "" then ", ";
    result += item;
}

in the first iteration it adds "" to the result in all others it adds ", ", so you get a string that contains each item separated by commas.

掩于岁月 2024-10-11 22:52:50
if (cond)
   //do something
else (cond)
   //do something
else (cond)
   //do something
first
   //do something
then
   //do something
else (cond)
   //do something
else
   //do something
end

如果 3 个条件中的任何一个被评估为 true,则 FIRST 和 THEN 块将运行。 FIRST 块在条件块之前运行,THEN 在条件块运行之后运行。

FIRST 和 THEN 语句之后的 ELSE 条件或最终写入独立于这些块。

它可以读作:

if (cond)
   first()
   //do something
   then()
else (cond)
   first()
   //do something
   then()
else (cond)
   first()
   //do something
   then()
else (cond)
   //do something
else
   //do something
end


function first()
   //do something
return
function then()
   //do something
return

这些函数只是一种阅读形式。他们不会创造范围。它更像是 Basic 的 gosub/return。

有用性和可读性作为讨论的问题。

if (cond)
   //do something
else (cond)
   //do something
else (cond)
   //do something
first
   //do something
then
   //do something
else (cond)
   //do something
else
   //do something
end

FIRST and THEN blocks runs if any of 3 conditionals are evaluated to true. FIRST block runs before the conditional block and THEN runs after the conditional block has ran.

ELSE conditional or final write following FIRST and THEN statement are independent from these blocks.

It can read as :

if (cond)
   first()
   //do something
   then()
else (cond)
   first()
   //do something
   then()
else (cond)
   first()
   //do something
   then()
else (cond)
   //do something
else
   //do something
end


function first()
   //do something
return
function then()
   //do something
return

These functions are just a form to read. They wouldn't create scope. It's more like a gosub/return from Basic.

Usefulness and readability as matter of discussion.

一紙繁鸢 2024-10-11 22:52:50

怎么样

alternate {
    statement 1,
    statement 2,
    [statement 3,...]
}

在每次连续传递中循环遍历可用语句

编辑:简单的示例

table_row_color = alternate(RED, GREEN, BLUE);

player_color = alternate(color_list); // cycles through list items

alternate(
    led_on(),
    led_off()
);

编辑2:在上面的第三个示例中,语法可能有点令人困惑,因为它看起来像一个函数。事实上,每次传递仅评估一个语句,而不是同时评估两者。更好的语法可能是类似

alternate {
    led_on();
}
then {
    led_off();
}

Or 的东西。不过,我确实喜欢这样的想法:如果需要,可以使用调用的结果(如颜色示例中所示)。

How about

alternate {
    statement 1,
    statement 2,
    [statement 3,...]
}

for cycling through the available statements on each successive pass.

Edit: trivial examples

table_row_color = alternate(RED, GREEN, BLUE);

player_color = alternate(color_list); // cycles through list items

alternate(
    led_on(),
    led_off()
);

Edit 2: In the third example above the syntax is maybe a bit confusing as it looks like a function. In fact, only one statement is evaluated on each pass, not both. A better syntax might be something like

alternate {
    led_on();
}
then {
    led_off();
}

Or something to that effect. However I do like the idea that the result of which ever is called can be used if desired (as in the color examples).

冷了相思 2024-10-11 22:52:50

D 的 范围保护 是一个非常有用的控制结构,但并不常见。

D's scope guards are a useful control structure that isn't seen very often.

微凉 2024-10-11 22:52:50

我想我应该提到 CityScriptCityDesk 的脚本语言)一些非常奇特的循环结构。

来自帮助文件:

{$ forEach n var in (condition) sort-order $}
... text which appears for each item ....
{$ between $}
.. text which appears between each two items ....
{$ odd $}
.. text which appears for every other item, including the first ....
{$ even $}
.. text which appears for every other item, starting with the second ....
{$ else $}
.. text which appears if there are no items matching condition ....
{$ before $}
..text which appears before the loop, only if there are items matching condition
{$ after $}
..text which appears after the loop, only of there are items matching condition
{$ next $}

I think I should mention CityScript (the scripting language of CityDesk) which has some really fancy looping constructs.

From the help file:

{$ forEach n var in (condition) sort-order $}
... text which appears for each item ....
{$ between $}
.. text which appears between each two items ....
{$ odd $}
.. text which appears for every other item, including the first ....
{$ even $}
.. text which appears for every other item, starting with the second ....
{$ else $}
.. text which appears if there are no items matching condition ....
{$ before $}
..text which appears before the loop, only if there are items matching condition
{$ after $}
..text which appears after the loop, only of there are items matching condition
{$ next $}
想挽留 2024-10-11 22:52:50

另请注意,许多控制结构在单子上下文中获得了新的含义,具体取决于特定的单子 - 看看 Haskell 中的 mapM、filterM、whileM、sequence 等。

Also note that many control structures get a new meaning in monadic context, depending on the particular monad - look at mapM, filterM, whileM, sequence etc. in Haskell.

寄离 2024-10-11 22:52:50

ignoring - 忽略某个代码块中发生的异常。

try {
  foo()
} catch {
  case ex: SomeException => /* ignore */
  case ex: SomeOtherException => /* ignore */
}

使用ignoring 控制结构,您可以将其编写得更简洁、更易读,如下所示:

ignoring(classOf[SomeException], classOf[SomeOtherException]) {
  foo()
}

[ Scala 在其标准库中的 util.control< 中提供了此功能(以及许多其他异常处理控制结构) /代码> 包。 ]

ignoring - To ignore exceptions occuring in a certain block of code.

try {
  foo()
} catch {
  case ex: SomeException => /* ignore */
  case ex: SomeOtherException => /* ignore */
}

With an ignoring control construct, you could write it more concisely and more readably as:

ignoring(classOf[SomeException], classOf[SomeOtherException]) {
  foo()
}

[ Scala provides this (and many other Exception handling control constructs) in its standard library, in util.control package. ]

残花月 2024-10-11 22:52:50

我想看到用于分组输出的关键字。与其这样:

        int lastValue = 0;

        foreach (var val in dataSource)
        {
            if (lastValue != val.CustomerID)
            {                    
                WriteFooter(lastValue);
                WriteHeader(val);
                lastValue = val.CustomerID;
            }
            WriteRow(val);
        }
        if (lastValue != 0)
        {
            WriteFooter(lastValue);
        }

不如这样:

        foreach(var val in dataSource)
        groupon(val.CustomerID)
        {            
            startgroup
            {
                WriteHeader(val);
            }
            endgroup
            {
                WriteFooter(val)
            }
        }
        each
        {
            WriteRow(val);
        }

如果您有一个不错的平台、控件和/或报告格式,您将不需要编写此代码。但令人惊讶的是我发现自己经常这样做。最烦人的部分是最后一次迭代之后的页脚 - 在现实生活中的示例中很难在不重复代码的情况下做到这一点。

I'd like to see a keyword for grouping output. Instead of this:

        int lastValue = 0;

        foreach (var val in dataSource)
        {
            if (lastValue != val.CustomerID)
            {                    
                WriteFooter(lastValue);
                WriteHeader(val);
                lastValue = val.CustomerID;
            }
            WriteRow(val);
        }
        if (lastValue != 0)
        {
            WriteFooter(lastValue);
        }

how about something like this:

        foreach(var val in dataSource)
        groupon(val.CustomerID)
        {            
            startgroup
            {
                WriteHeader(val);
            }
            endgroup
            {
                WriteFooter(val)
            }
        }
        each
        {
            WriteRow(val);
        }

If you have a decent platform, controls, and/or reporting formatting you won't need to write this code. But it's amazing how often I find myself doing this. The most annoying part is the footer after the last iteration - it's hard to do this in a real life example without duplicating code.

饮惑 2024-10-11 22:52:50

bool found = false;
for (int i = 0; i < N; i++) {
  if (hasProperty(A[i])) {
    found = true;
    DoSomething(A[i]);
    break;
  }
}
if (!found) {
  ...
}

for (int i = 0; i < N; i++) {
  if (hasProperty(A[i])) {
    DoSomething(A[i]);
    break;
  }
} ifnotinterrupted {
  ...
}

我总觉得必须有一种更好的方法,而不是引入一个标志只是为了在循环体的最后一次(常规)执行之后执行某些操作 人们可以检查 !(i < N),但是 i 在循环后超出了范围。

Something that replaces

bool found = false;
for (int i = 0; i < N; i++) {
  if (hasProperty(A[i])) {
    found = true;
    DoSomething(A[i]);
    break;
  }
}
if (!found) {
  ...
}

like

for (int i = 0; i < N; i++) {
  if (hasProperty(A[i])) {
    DoSomething(A[i]);
    break;
  }
} ifnotinterrupted {
  ...
}

I always feel that there must be a better way than introducing a flag just to execute something after the last (regular) execution of the loop body. One could check !(i < N), but i is out of scope after the loop.

风吹过旳痕迹 2024-10-11 22:52:50

这有点开玩笑,但你可以得到你想要的行为,如下所示:

#include <iostream>
#include <cstdlib>

int main (int argc, char *argv[])
{
  int N = std::strtol(argv[1], 0, 10); // Danger!
  int state = 0;
  switch (state%2) // Similar to Duff's device.
  {
    do {
      case 1: std::cout << (2*state) << " B" << std::endl;
      case 0: std::cout << (2*state+1) << " A" << std::endl; ++state;
    } while (state <= N);
      default: break;
  }

  return 0;
}

ps 格式化这有点困难,我绝对不满意它;然而,emacs 的表现更糟。有人想尝试一下 vim 吗?

This is a bit of a joke, but you can get the behavior you want like this:

#include <iostream>
#include <cstdlib>

int main (int argc, char *argv[])
{
  int N = std::strtol(argv[1], 0, 10); // Danger!
  int state = 0;
  switch (state%2) // Similar to Duff's device.
  {
    do {
      case 1: std::cout << (2*state) << " B" << std::endl;
      case 0: std::cout << (2*state+1) << " A" << std::endl; ++state;
    } while (state <= N);
      default: break;
  }

  return 0;
}

p.s. formatting this was a bit difficult and I'm definitely not happy with it; however, emacs does even worse. Anyone care to try vim?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文