是否有一些 "StringToEnum "的函数或替代方法? - 页 2

 

我一直在关注这个问题,但我不清楚你到底想要完成什么。

我通常会通过不同的方式对事情进行重新编码,最终达到我所寻找的最终结果,事情可以通过很多方式完成。

 
Marco vd Heijden:

我一直在关注这个问题,但我不清楚你到底想要完成什么。

我通常会通过不同的方式对事情进行重新编码,最终达到我所寻找的最终结果,事情可以通过很多方式完成。

谢谢你,马可。当然,事情可以有很多方法(和变通方法),有时你必须选择其中一种方法来完成你的目标,但有些方法比其他方法容易。在这种情况下,我采取的变通方法是模仿函数。 StringToEnum使用了多个字符串比较的 "if",但是正如我之前所说的,eval函数(在mql5中没有实现)可以帮助避免所有这些if,并且也有助于维护,因为如果常量改变了它们的名字,那么你就不必改变if块。
 

我完全明白你的意思,我在一个代码块中有几百个,有时甚至几千个if行来达到我的要求。

你必须热爱你的工作。

 
cyberglassed:
谢谢你,Marco。当然,事情可以有很多方法(和变通方法),有时你必须选择其中一种方法来完成你的目标,但有些方法比其他方法容易。在这种情况下,我采取的变通方法是模仿函数。StringToEnum使用了多个字符串比较的 "if",但是正如我之前所说,eval函数(在mql5中没有实现)可以帮助避免所有这些if,也有助于维护,因为如果常数改变了它们的名字,那么你就不必改变if块。

你能解释一下,为什么你需要这个StringToEnum吗?很明显,你有一个带有枚举值的字符串,但为什么它是在一个字符串上?我很想知道。

换句话说,在eval(...) 函数的支持下,我们可以同时解决很多问题。

这永远不会发生,不要在这上面浪费时间。Eval()函数 是一扇开放的安全漏洞之门,Metaquotes不会添加这样的函数。

 
Marco vd Heijden:

我完全明白你的意思,我在一个代码块中有几百个,有时甚至几千个if行来达到我的要求。

你必须热爱你的工作。

你的问题不能用StringToEnum()来解决,你已经知道了(我想)。
 
Alain Verleyen:
你的问题不能用StringToEnum()来解决,你已经知道了(我想)。

正确,但可以倒过来做。

  int b=0;
  
  if(EnumToString(MODE_SMMA)=="MODE_SMMA"){b=2;Print("b= ",b);}

但这将是毫无意义的,因为MODE_SMMA已经有了整数值2,这就是为什么我写道,我不明白cyberglassed 想要达到什么目的。

 
Marco vd Heijden:

正确,但可以倒过来做。

但这将是毫无意义的,因为MODE_SMMA已经有了整数值2,这就是为什么我写道,我不明白cyberglassed 想要达到什么目的。

马可,我使用的解决方法是如下的(非常简约的版本)。

int StringToEnum(string strId) {
        if (false) {}
        else if (strId == "PRICE_CLOSE")     return 1;
        else if (strId == "PRICE_OPEN")      return 2;
        else if (strId == "PRICE_HIGH")      return 3;
        else if (strId == "PRICE_LOW")       return 4;
        else if (strId == "PRICE_MEDIAN")    return 5;
        else if (strId == "PRICE_TYPICAL")   return 6;
        else if (strId == "PRICE_WEIGHTED")  return 7;
        // ...
        return -1;
}

void OnStart() {
        string strId = "PRICE_MEDIAN";
        printf("%s: %d ", strId, StringToEnum(strId));
}

当然,我不是从常数开始,而是从一个字符串开始,我这么说是因为你的代码中写了以下内容。

EnumToString(MODE_SMMA)

就像你从一开始就有常数本身一样。

如果我误解了你的意思,对不起,我的英语不是很好。

谢谢。

 
Alain Verleyen:

你能解释一下,为什么你需要这个StringToEnum。很明显,你有一个带有枚举值的字符串,但是为什么它是在一个字符串上?我很想知道。

换句话说,在eval(...) 函数的支持下,我们可以同时解决很多问题。

这永远不会发生,不要在这方面浪费时间。Eval()函数是一扇开放的安全漏洞之门,Metaquotes不会添加这样的函数。

嗨,Alain,我满足了你的好奇心:P

想象一下,你正在使用多个外部mql5代码,然后你正在处理多个定义在上面的 "enum "数据类型,当然,像人类一样,你最好记住每个 "enum "的每个值的字符串名称。然后在某些部分,你想用字符串格式 指定某个枚举的某些值,那么你不能直接这样做,所以你必须使用我上面写的一些变通方法。这有两个很大的缺点,第一个是你必须收集所有涉及到的枚举的所有值,第二个缺点是维护,所以如果你更新了一些外部的mql5代码,开发人员改变了与一些常数表示相关的int值,那么你可能会得到意想不到的行为,所以你必须不断检查代码的更新。

关于安全漏洞的话题...我并不完全同意你所说的它是一扇安全漏洞的大门。当然,它可能是一扇敞开的大门,但作为程序员,你必须设置限制,并照顾到可能的关键情况,我的意思是你可以完美地管理这种情况,如在PHP中,甚至在SQL中的代码注入,你必须解析一些可能来自用户的关键输入数据,以防他们访问你的代码。

也许将来我们会有一点运气,开发者团队可以在这个方向上给我们一些帮助,所以现在,我们可以使用变通的方法:P

 
cyberglassed:

马可 我使用的解决方法如下(非常简约的版本)。

当然,我不是从常数开始,而是从一个字符串开始,我这么说是因为你的代码中写了以下内容。

就像你从一开始就有了常数本身。

如果我误解了你的意思,对不起,我的英语不是很好。

谢谢。

这就是为什么它被称为倒退,你从比较所有的枚举开始,从字符串 中溶解出枚举 值。

int b;
if(EnumToString(MODE_SMA)=="MODE_SMA"){b=0;}
if(EnumToString(MODE_EMA)=="MODE_EMA"){b=1;}
if(EnumToString(MODE_SMMA)=="MODE_SMMA"){b=2;}
if(EnumToString(MODE_LWMA)=="MODE_LWMA"){b=3;}

Print(b);


但这不是同样的事情吗?

不管你在哪一边比较,如果有一个匹配的字符串,它就会把值标记为b。

int b;
if("MODE_SMA"==EnumToString(MODE_SMA)){b=0;}
if("MODE_EMA"==EnumToString(MODE_EMA)){b=1;}
if("MODE_SMMA"==EnumToString(MODE_SMMA)){b=2;}
if("MODE_LWMA"==EnumToString(MODE_LWMA)){b=3;}

Print(b);

所以在这里我们从一个字符串值开始,但有什么不同呢?

没有。

 
Marco vd Heijden:

...

但这不是同样的事情吗?

不管你在哪一边进行比较,如果有一个匹配,它就会把值签成b。

int b;
if("MODE_SMA"==EnumToString(MODE_SMA)){b=0;}
if("MODE_EMA"==EnumToString(MODE_EMA)){b=1;}
if("MODE_SMMA"==EnumToString(MODE_SMMA)){b=2;}
if("MODE_LWMA"==EnumToString(MODE_LWMA)){b=3;}

Print(b);

所以在这里我们从一个字符串值开始,但有什么不同呢?

没有。

你上面的代码是无用的,因为它总是返回 "b = 3"(最后一个 "if",因为你没有使用 "else if")。

如果你使用 "else if",那么它将总是返回 "b = 0"。

总之,信息。每次都是 "b = 3",并没有提供任何信息。