我有一个特殊的类用作方法的返回类型,其中包含所需的值,或者在失败的情况下包含错误消息,该消息甚至是从以前的错误级联而来的。它按预期工作。
由于返回的类型不同地复杂,我喜欢使用关键字auto。但是当使用许多方法时,我必须创建新的返回变量。
代码的典型部分如下所示:
auto ret1 = methodA();
if(ret1.isValid()...
auto ret2 = methodB();
if(ret2.isValid()...
我不喜欢总是创建一个新的变量。但我喜欢优雅的错误处理方式。使用更转储的返回类型(如integer中的错误代码(可以解决问题,但我从错误处理返回类型中没有任何好处。
有什么技巧可以重用第一个返回变量ret1
吗?
您必须创建新的作用域才能为不同的变量重用变量名,例如:
{
auto ret = methodA();
if (ret.isValid()) ...
}
{
auto ret = methodB();
if (ret.isValid()) ...
}
您还可以利用if
创建的作用域,将init语句放在中
if (auto ret = methodA(); ret.isValid()) ...
if (auto ret = methodB(); ret.isValid()) ...
auto
不是类型。
这是一个关键字,上面写着"通过从初始值推导,将类型放在这里"。这种情况在编译过程中发生过一次。
无论是否使用auto
,都不能重用ret1
来存储不同类型的对象。
这应该不是什么大问题。如果你担心"名字不够用",或者"有很多相似的名字",那么你的名字不够描述性,或者你的范围不够紧凑。
auto
不是类型。在auto foo = bar();
中,编译器只需计算出bar()
实际返回的类型,并将其代入。因此,如果bar()
返回int
,则这是foo
的类型,如果它返回bool
,则是foo
的类型。一旦auto
应该被替换的类型(第一次(已经确定,那么它就可以永远改变。auto
并不意味着"变量类型",它只是意味着"嘿,编译器,我太懒了,想不出要放在这里的类型,请帮我做",但与你自己写最终类型相比,没有什么区别。因此,如果第二次分配给变量的类型与第一次相同,则可以重用该变量,否则就不能重用。
我不喜欢总是创建一个新变量。
最好创建一个const
变量:
const auto ret1 = methodA();
if(ret1.isValid()...
const auto ret2 = methodB();
if(ret2.isValid()...
在这种情况下,您需要使const
具有与isValid
类似的所有方法,但这更好:"is"不应该有副作用并修改状态。
下一步是完全删除临时变量:
if(methodA().isValid()) {
...
}
if(methodB().isValid()) {
...
}
另一种选择是将每个函数调用封装到一个块中:
{
const auto ret = methodA();
if(ret.isValid()...
}
{
const auto ret = methodB();
if(ret.isValid()...
}
这允许您重用const变量名。
每个块都成为提取到一个单独函数中的候选者(请参阅"Clean Code"中的Uncle Bob(。