1

With the following enum definition in Solidity code...

enum Direction { North, South, East, West }

... I would like to set up a for-loop that iterates over this enum's values, e.g.

for (uint8 dirn = 0; dirn < xxx; dirn++) { ... }

Is there a way for the code to check what the size of the enum is, i.e. what should replace xxx, other than the hard-coded literal value 4?

  • Enums are hardcode explicitly on your code, there's no reason to try a dynamic approach to loop through them, perhaps you trying an antipattern – Eduardo Pereira Jun 30 '18 at 12:44
  • I was new to Ethereum at the time I posted this, coming from the Java world, where every enum has a static method values() that returns an array of all the enum constants, and each enum has a method name() and ordinal(). That is perhaps useful when the enum is defined in a 3rd-party jar. I guess that would not be a relevant use case in Ethereum. Or could it be useful when using libraries (i.e. EthPM packages)? I do not have an actual use case. I was just trying to expand my knowledge of Solidity. – Ajoy Bhatia Jul 2 '18 at 2:54
  • A possible use could be if a public function takes an enum as an argument. The caller of that function will pass an integer value. Within the function, the arg value would need to be checked to be within the enum range. Now, it could just be checked to be less than a literal integer, which is the number of all enum values. But one could say that having a dynamic way to get the valid range would be better than having to take care that any literal values in checks are kept in sync with any changes to an enum's values. (e.g. if a developer takes some code and edits it to create a new contract) – Ajoy Bhatia Jul 2 '18 at 3:15
0

Possibly here is what you can do.

  1. Declare array to store the enum choices
  2. In constructor call push all the enum choices in the array
  3. In the method to match the enum choice just loop the array and match it against the passed enum choice
  • Yes, that is a way to explicitly do it, just like string comparison needs to be done explicitly byte-by-byte. I was wondering if there is a more direct way to do this. I will wait for some time to see if someone else knows it before I mark this as an answer. – Ajoy Bhatia Apr 12 '17 at 19:16
  • Just using the literal value 4 would be easier than the above. Just that anyone adding more values to the enum should remember to change the limit in the for-loop, too. But if new enum values being added is very rare or unlikely, then going with the literal enum size is better gas-wise. Haven't checked what the gas difference would be. Could be negligible but still non-zero. – Ajoy Bhatia Apr 12 '17 at 19:23
  • Completely agree, but because you wanted something dynamic so came up with it. – Susmit Apr 13 '17 at 4:18
0

In your case you don't want to use a for loop, but a while loop:

enum Direction { North, South, East, West }

uint8 dirn = 0;
while (dirn <= Direction.West) { 
   // do stuff
   dirn++;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.