Godot: Classes are not considered constants in GDScript

Created on 10 Nov 2019  路  11Comments  路  Source: godotengine/godot

Godot 3.2 alpha1

The following examples all produce an Expected a constant expression error:

class Test:
    var a

const test = Test
const test2 = [Test]
const test3 = {"test": Test}

I wanted to use a class in a constant, but it's not possible, while it is possible with scripts obtained with preload.

bug gdscript

Most helpful comment

Doesn't need to be runtime, we can tell which class it is at compilation time. We just need to make the parser know that this case can be considered constant. The compiler will already have a script reference to place there when needed.

But const are static to the script not var this issue need something to be static to the script value can be set at runtime (and may be immutable)

This can become quite complex, but it isn't need to solve this particular issue. If you think this can be useful in an specific case, you can open a proposal: https://github.com/godotengine/godot-proposals/issues/573

All 11 comments

our const are compile time constants so when compiling the script the class Test is not a gd script instance (until the compilation ends), but the preload returns the gd script instance which was compiled before.

I think we have to make our const as runtime constants, or may be we could add a "subclass compiler" to the parser to compile the subclass after parsing the subclass to make a script instance.
or may be any other workaround ??

@vnen @bojidar-bg

This might be related to the usual reference cycle problem. Consider:

class X:
    func do_stuff():
        return Y[0].new()
const Y = [X]

yeah, still we can do this

class X:
    func do_stuff() -> X:
        return [X][0].new()

runtime constant resolve the reference cycle problem (but changing runtime const might break our old stuff).
how about introduce a new keyword like readonly for runtime const (like c#)??
@bojidar-bg

how about introduce a new keyword like readonly for runtime const (like c#)??

Support for immutable variables is being tracked in #23695.

@Calinou
But const are static to the script not var this issue need something to be static to the script value can be set at runtime (and may be immutable)

## script.gd
extends Node
const c = 3
var v = 3
extends Node2D
var script = preload("res://script.gd")
func _init():
    script.c ## valid
    script.v ## invalid
    script.new().v ## valid

Doesn't need to be runtime, we can tell which class it is at compilation time. We just need to make the parser know that this case can be considered constant. The compiler will already have a script reference to place there when needed.

But const are static to the script not var this issue need something to be static to the script value can be set at runtime (and may be immutable)

This can become quite complex, but it isn't need to solve this particular issue. If you think this can be useful in an specific case, you can open a proposal: https://github.com/godotengine/godot-proposals/issues/573

I'm not sure if this is the same or related issue...

If the class is defined in a separate file, then assignment to a const is allowed. HOWEVER, GDScript doesn't infer static type as it does with a var...

# math.gd

class_name Math

static func sum(a: float, b: float) -> float:
    return a + b

Different files...

const math := Math # this is ok

var c: float = math.sum(1.0, 2.0) # this is ok
var d := math.sum(1.0, 2.0) # Error: "The assigned value does not have a set type..."
var math := Math

var d := math.sum(1.0, 2.0) # this is ok



md5-48464e31a788b8914c70593bab66ab0e



const math := preload("res://math.gd")

var d := math.sum(1.0, 2.0) # this is ok

(3.2.1 stable)

@charliewhitfield
see:
#37380
https://github.com/godotengine/godot/issues/37380#issuecomment-607576131

@ThakeeNathees, thanks for the links, but I'm failing to see the relevance. My post is about the behavior of regular file classes assigned to const, which "works" (unlike inner classes) but does not allow static typing as I expected. I edited my code and comments above to make this point more clear. I may have misjudged its relationship to this issue (or even if I have an issue). Please enlighten me before I open a separate issue.

@charliewhitfield oh It's a completely different situation, sorry for that, I think you should create a new issue so someone can fix it.

OK. I agree it is different than either existing issue. I'll open a new one.

Was this page helpful?
0 / 5 - 0 ratings