这个“成语”有更好的方法吗?
if(State s = loadSomething()) { } else return s;
换句话说,我想做一些事情,可能会返回错误(带有消息)或成功状态,如果有错误我想要返回它。这可能变得非常重复,所以我想缩短它。例如
if(State s = loadFoobar(&loadPointer, &results)) { } else return s;
if(State s = loadBaz(&loadPointer, &results)) { } else return s;
if(State s = loadBuz(&loadPointer, &results)) { } else return s;
这不能使用我不喜欢的异常(不适合此版本)。我可以编写一个存储值的小类BooleanNegator<State>
,并否定它的布尔值。但我想避免这样做,并且更喜欢增强/标准解决方案。
答案 0 :(得分:10)
你可以这样做:
for (State s = loadSomething(); !s; ) return s;
但我不确定它是否更优雅,而且它的可读性肯定更低......
答案 1 :(得分:3)
我认为上下文类似于
State SomeFunction()
{
if(State s = loadSomething()) { } else return s;
return do_something_else();
}
不会抛出do_something_else()
与SomeFunction()
有关并且返回State
的例外情况。无论哪种方式,在函数内继续的结果都需要返回State
,因为从结尾处掉落将导致调用者表现出未定义的行为。
在这种情况下,我只是将函数重构为
State SomeFunction()
{
if (State s = loadSomething())
return do_something_else();
else
return s;
}
隐含的假设是State
有一些可以测试的运算符(例如operator bool()
),复制State
是可能的(隐含loadSomething()
的存在返回一个并且相对便宜,并且State
的两个实例可以同时存在。
答案 2 :(得分:3)
除了使用不同关键字的智能/ hacky来获得相同的行为,或者添加或多或少复杂的额外模板或宏来获取unless()
关键字或以某种方式设法注入!
操作员,我只坚持基本的事情。
这是我(可能)注入额外&#34;不必要&#34;的地方之一。括号:
void someFunction()
{
// some other code
{ State s = loadSomething(); if(!s) return s; }
// some other code
}
但是,在这种情况下,我会对其进行扩展,以强调return
关键字,当它被压缩为单行时,很容易被忽略。因此,除非单行重复多次,除非它明确且明显地内部有return
,否则我可能写道:
void someFunction()
{
// some other code
{
State s = loadSomething();
if(!s)
return s;
}
// some other code
}
它可能看起来像提升s
的范围,但实际上它相当于在State s
中声明if()
。所有这些都要归功于明确限制本地s
的可见性的额外括号。
然而,有些人只是讨厌&#34;看到{ .. }
没有与关键字/类/功能/等结合,或者甚至认为它是不可读的,因为&#34;提示if / while / etc关键字被意外删除&#34;。
在添加重复示例后,又有一个想法来找我。您可以尝试使用脚本语言中的一种技巧,其中&&
和||
可能会返回非bool值:
State s = loadFoobar(&loadPointer, &results);
s = s || loadBaz(&loadPointer, &results);
s = s || loadBuz(&loadPointer, &results);
if(!s) return s;
但是存在一个问题:与脚本语言相比,在C ++中&&
和||
lose their short-circuit semantics的重载使得这种尝试毫无意义。
但是,正如 dyp 指出的那样,显而易见的是,s
范围提升后,现在可以引入简单的if
。可以使用额外{}
:
{
State s;
if(!(s = loadFoobar(&loadPointer, &results))) return s;
if(!(s = loadBaz(&loadPointer, &results))) return s;
if(!(s = loadBuz(&loadPointer, &results))) return s;
}