如何有效地将if和else用于筛选构造
How to effectively use if and else for a filtering construct?
要解析从JavaScript获得的函数参数,我需要执行大量检查。例如,一个函数可能期望一个对象作为参数,在JavaScript中看起来像这样。
{
Fullscreen: [ 'bool', false ],
Size: [ 'Vector2u', 800, 600 ],
Title: [ 'string', 'Hello World' ],
// more properties...
}
在C++中,我通过循环遍历所有键并检查它们来解析它。如果其中一项检查失败,则应打印一条错误消息,并跳过此键值对。这就是我目前的实现情况。我希望你不要因为某些特定于引擎的呼叫而分心。
ModuleSettings *module = (ModuleSettings*)HelperScript::Unwrap(args.Data());
if(args.Length() < 1 || !args[0]->IsObject())
return v8::Undefined();
v8::Handle<v8::Object> object = args[0]->ToObject();
auto stg = module->Global->Get<Settings>("settings");
v8::Handle<v8::Array> keys = object->GetPropertyNames();
for(unsigned int i = 0; i < keys->Length(); ++i)
{
string key = *v8::String::Utf8Value(keys->Get(i));
if(!object->Get(v8::String::New(key.c_str()))->IsArray())
{
HelperDebug::Fail("script", "could not parse (" + key + ") setting");
continue;
}
v8::Handle<v8::Array> values = v8::Handle<v8::Array>::Cast(object->Get(v8::String::New(key.c_str())));
if(!values->Has(0) || !values->Get(0)->IsString())
{
HelperDebug::Fail("script", "could not parse (" + key + ") setting");
continue;
}
string type = *v8::String::Utf8Value(values->Get(0));
if(type == "bool")
{
if(!values->Has(1) || !values->Get(1)->IsBoolean())
{
HelperDebug::Fail("script", "could not parse (" + key + ") setting");
continue;
}
stg->Set<bool>(key, values->Get(1)->BooleanValue());
}
else if(type == "Vector2u")
{
if(!values->Has(1) || !values->Has(2) || !values->Get(1)->IsUint32(), !values->Get(2)->IsUint32())
{
HelperDebug::Fail("script", "could not parse (" + key + ") setting");
continue;
}
stg->Set<Vector2u>(key, Vector2u(values->Get(1)->Uint32Value(), values->Get(2)->Uint32Value()));
}
else if(type == "string")
{
if(!values->Has(1) || !values->Get(1)->IsString())
{
HelperDebug::Fail("script", "could not parse (" + key + ") setting");
continue;
}
stg->Set<string>(key, *v8::String::Utf8Value(values->Get(1)));
}
}
正如您所看到的,我定义了当每个过滤器的检查失败时发生的情况。
HelperDebug::Fail("script", "could not parse (" + key + ") setting");
continue;
我只想写一次,但我只能想出一种使用goto
的方法,我想阻止它。是否有更好的选择来重构if
else
结构?
我想我应该从一组小类开始,为每种类型做验证步骤:
auto v_string = [](v8::Handle<v8::Array> const &v) {
return v->Has(1) && v->Get(1)->IsString();
}
auto v_Vector2u = [](v8::Handle<v8::Array> const &v) {
return v->Has(1) && v->Has(2) &&
v->Get(1)->IsUint32() && v->Get(2)->IsUint32();
}
// ...
然后我会创建一个从类型名称到该类型验证器的映射:
std::map<std::string, decltyp(v_string)> verifiers;
verifiers["string"] = v_string;
verifiers["Vector2u"] = v_Vector2u;
// ...
然后为了验证一个类型,你可以使用这样的东西:
// find the verifier for this type:
auto verifier = verifiers.find(type);
// If we can't find a verifier, reject the data:
if (verifier == verifiers.end())
HelperDebug::Fail("script", "unknown type: " + type);
// found the verifier -- verify the data:
if (!verifier->second(values))
HelperDebug::Fail("script", "could not parse (" + key + ") setting");
对于这种情况,一种非常常见的方法是使用宏。这是在函数之前或函数中定义的#,在函数末尾定义的#。由于您需要continue
,所以其他方式基本上都被冲洗掉了。
goto也是一个解决方案,但对于这个特定的样品,我不会使用它。
一种更轻松的方法是至少将失败调用放入函数或lambda中,这仍然会留下continue部分。
我可能会制作一个以过滤器表达式为参数的宏,留下这样的代码。
if(type == "bool")
{
ENSURE(values->Has(1) && values->Get(1)->IsBoolean());
stg->Set<bool>(key, values->Get(1)->BooleanValue());
}
...
相关文章:
- 1d 智能指针不适用于语法 (*)++
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 用于访问容器<T>数据成员的正确 API
- 重载操作程序时出错>>用于类中的字符串 memebr
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- C++中的cin.ignore()函数不适用于整个流
- 没有用于初始化C++中的变量模板的匹配构造函数
- 用于C++中带有数组和指针的循环
- 为什么它不适用于Visual 2019的原因
- 使用在用于SFINAE的void_t中具有参数的方法
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 重载==不适用于二进制树
- Insert函数不适用于2 if语句C++
- 用于矢量处理的多个线程
- 使外部项目可用于find_package CMake
- 用于直接显示筛选器的 CoCreateInstance 返回E_NOINTERFACE
- InfTee 筛选器不适用于 VMR
- 编译适用于 Windows 7 的 Windows 8 微筛选器驱动程序
- 用于 x264 DirectShow 筛选器的 CLSID
- 如何有效地将if和else用于筛选构造