How can I use enums in match sentence?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By oleg.budin

Sometimes I need to store enums integer value to file. When I load this value, I get integer.
How can I cast that value to enum type to use in match sentence?

  1. Enums in GDScript can’t be used in typed var declaration like
var my_var : G.MY_ENUM = G.MY_ENUM.VALUE_1

or

var my_var := G.MY_ENUM.VALUE_1

(Especially when enum declared, for example, in singleton G)

  1. There’s no possibility to cast by “as” for the same reason
match my_int_var as  G.MY_ENUM:
  1. match interpretes equal int and enum values as different ones (unlike == operator)

P.S. If I use enums of constants with int values I have to use if/elif/else sentence instead of match

SOLVED!
The reason was misunderstanding the type of var in match (I got it from parse_json() function, that parses all numeric values as floats and there are no methods to distinquish type of variable in debugger)
Moreover the to_json() function converts enum values to strings and i do not know how to convert them back after parse_json() call.

match interpretes equal int and enum values as different ones

…what exactly do you mean, or else, could you provide a code snippet of what’s not working for you? I tried what I thought you were asking about with the following script:

tool
extends EditorScript

enum my_enum { ONE=1, TWO=2, THREE=3 }

func _run():
  for i in [1,2,3]:
    print("comparing " + str(i))
    match i:
      1:
        print("1")
        continue
      2:
        print("2")
        continue
      3:
        print("3")
        continue
      my_enum.ONE:
        print("my_enum.ONE")
        continue
      my_enum.TWO:
        print("my_enum.TWO")
        continue
      my_enum.THREE:
        print("my_enum.THREE")
        continue

func _ready() -> void:
  pass

…when run, it prints:

comparing 1
1
my_enum.ONE
comparing 2
2
my_enum.TWO
comparing 3
3
my_enum.THREE

…which is exactly what one would expect, and also exactly what you’re asking for, that is, if I’ve understood you correctly.

jhigginbotham64 | 2019-10-18 04:58

Thanks for reply!
My mistake was in misunderstanding work of to_json/parse_json

In singleton named G:

enum RockHolderType {
	NO_ROCK = 0,
	OBLIGATORY_STAR = 1,
	COMET = 2,
	BLACK_HOLE = 3,
	ROCK = 4,
}

In main code:

func check_result():
	for k in [ G.RockHolderType.NO_ROCK, 
				G.RockHolderType.OBLIGATORY_STAR,
				G.RockHolderType.COMET, 
				G.RockHolderType.BLACK_HOLE,
				G.RockHolderType.COMET, 
				G.RockHolderType.ROCK ]:
		print("\nValue k = ", k)
		var x = { k = k }
		var json = to_json(x)
		var s = parse_json(json)
		var j = s["k"]
		match j:
			G.RockHolderType.NO_ROCK:
				print ("(NO_ROCK) j = ", j)
			G.RockHolderType.ROCK:
				print ("(ROCK) j = ", j)
			G.RockHolderType.OBLIGATORY_STAR:
				print ("(STAR) j = ", j)
			G.RockHolderType.COMET:
				print ("(COMET) j = ", j)
			G.RockHolderType.BLACK_HOLE:
				print ("(BLACK_HOLE) j = ", j)
			_:
				print("NOT IN ENUM j = ", j)
		print("But!")
		if j ==	G.RockHolderType.NO_ROCK:
				print ("(NO_ROCK) j = ", j)
		elif j == G.RockHolderType.ROCK:
				print ("(ROCK) j = ", j)
		elif j == G.RockHolderType.OBLIGATORY_STAR:
				print ("(STAR) j = ", j)
		elif j == G.RockHolderType.COMET:
				print ("(COMET) j = ", j)
		elif j == G.RockHolderType.BLACK_HOLE:
				print ("(BLACK_HOLE) j = ", j)
		else:
			print("else j = ", j)
	

Result:

Value k = 0
NOT IN ENUM j = 0
But!
(NO_ROCK) j = 0

Value k = 1
NOT IN ENUM j = 1
But!
(STAR) j = 1

Value k = 2
NOT IN ENUM j = 2
But!
(COMET) j = 2

Value k = 3
NOT IN ENUM j = 3
But!
(BLACK_HOLE) j = 3

Value k = 2
NOT IN ENUM j = 2
But!
(COMET) j = 2

Value k = 4
NOT IN ENUM j = 4
But!
(ROCK) j = 4

Looks like wrong behaviour, but actually parse_json returns TYPE_REAL value.
When debugging, I can’t see the type of j variable, if it has integer value (no decimal point or something else). Not good:(

P.S. Enums in GDScript is some kind of evil.

for l in G.RockHolderType:
		print("\nValue l = ", l, ", typeof(l) == TYPE_STRING is ", typeof(l) == TYPE_STRING)

Result:

Value l = NO_ROCK, typeof(l) == TYPE_STRING is True

Value l = OBLIGATORY_STAR, typeof(l) == TYPE_STRING is True

Value l = COMET, typeof(l) == TYPE_STRING is True

Value l = BLACK_HOLE, typeof(l) == TYPE_STRING is True

Value l = ROCK, typeof(l) == TYPE_STRING is True		

IMHO these string values is useless. I don’t know how to convert them to origin int

oleg.budin | 2019-10-18 10:25

Ok, that’s pretty important.

Adding an int cast to the following line

var j = s["k"]

so that it becomes

var j = int(s["k"])

fixes the output for me. Is that perhaps the answer you were looking for? If so, you may want to update your question with all the new information.

jhigginbotham64 | 2019-10-18 17:08