Initialize typed arrays with non trivial types

Godot Version

Godot_v4.4.1-stable_win64.exe

Question

I’ve read here and here about how to initialize typed arrays.
However, i’m struggling to do this for instances of a specific class, like

extends Node
class_name Pics
class Pic:
	var name : String
	static func create(name : String) -> Pic:
		var instance = Pic.new()
		instance.name = name
		return instance
@export var pics : Array[Pics.Pic] = [ Pic.create("asdf"), ] # Error: Trying to assign an array of type "Array" to a variable of type "Array[Pic]".

Is there a way to do this?

Using type casting seemed to eliminate the error, at least for me. Instead of @export var pics : Array[Pics.Pic] = [ Pic.create("asdf"), ], try @export var pics := [ Pic.create("asdf"), ] as Array[Pics.Pic].
See GDScript reference - Casting and Static typing in GDScript - Type casting.

2 Likes

Not sure what i’m doing wrong.
Now i get

Export type can only be built-in, a resource, a node, or an enum.

for

@export var pics := [ Pic.create("asdf"), ] as Array[Pics.Pic]

and

@export var pics : Array[Pics.Pic] = [ Pic.create("asdf"), ] as Array[Pics.Pic]

and

@export var pics : Array[Pics.Pic] = [ Pic.create("asdf"), ]

Without @export there are no errors.
I can’t seem to reproduce the old error

Trying to assign an array of type “Array” to a variable of type “Array[Pic]”

but

Export type can only be built-in, a resource, a node, or an enum.

makes it clear and i found a post which talks about this already.

Thanks for your help!

Export type can only be built-in, a resource, a node, or an enum.

This is because Pic currently is a class, but not one that inherits from Resource. You can fix this by making the Pic class extend a class that inherits from Resource, such as RefCounted.

extends Node
class_name Pics
class Pic:
    extends RefCounted
	var name : String
	static func create(name : String) -> Pic:
		var instance = Pic.new()
		instance.name = name
		return instance
@export var pics := [ Pic.create("asdf"), ] as Array[Pics.Pic]

The benefit of using RefCounted instead of Resource is that Pics will automatically be removed from memory when no references to them are held anymore.

From the RefCounted documentation:

Unlike other Object types, RefCounteds keep an internal reference counter so that they are automatically released when no longer in use, and only then. RefCounteds therefore do not need to be freed manually with Object.free().

1 Like

Thanks for the explanation.

I found that (maybe it changed?) Resource derives from RefCounted.
By deriving Pic from Resource, @export pics as typed array works.

@export var pics : Array[Pics.Pic] = [ Pic.create("asdf"), ]

Thanks a lot!

1 Like

My mistake, you’re correct.
I’m glad I could help!