From 6c3cef80b3f88e7571852d039b71c0e3d0a7df0a Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Wed, 5 Mar 2025 02:35:27 +0100 Subject: [PATCH] Document typed dictionaries in GDScript --- .../scripting/gdscript/gdscript_basics.rst | 27 +++++++++++++++++ .../scripting/gdscript/static_typing.rst | 29 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/tutorials/scripting/gdscript/gdscript_basics.rst b/tutorials/scripting/gdscript/gdscript_basics.rst index 72ffc6ce91e..eb88b2b36b7 100644 --- a/tutorials/scripting/gdscript/gdscript_basics.rst +++ b/tutorials/scripting/gdscript/gdscript_basics.rst @@ -979,6 +979,33 @@ assign to it:: this, use the :ref:`Object.get() ` and :ref:`Object.set() ` methods instead. +Typed dictionaries +^^^^^^^^^^^^^^^^^^ + +Godot 4.4 added support for typed dictionaries. On write operations, Godot checks that +element keys and values match the specified type, so the dictionary cannot contain invalid +keys or values. The GDScript static analyzer takes typed dictionaries into account. However, +dictionary methods that return values still have the ``Variant`` return type. + +Typed dictionaries have the syntax ``Dictionary[KeyType, ValueType]``, where ``KeyType`` and ``ValueType`` +can be any ``Variant`` type, native or user class, or enum. Both the key and value type **must** be specified, +but you can use ``Variant`` to make either of them untyped. +Nested typed collections (like ``Dictionary[String, Dictionary[String, int]]``) +are not supported. + +:: + + var a: Dictionary[String, int] + var b: Dictionary[String, Node] + var c: Dictionary[Vector2i, MyClass] + var d: Dictionary[MyEnum, float] + # String keys, values can be any type. + var e: Dictionary[String, Variant] + # Keys can be any type, boolean values. + var f: Dictionary[Variant, bool] + +``Dictionary`` and ``Dictionary[Variant, Variant]`` are the same thing. + :ref:`Signal ` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tutorials/scripting/gdscript/static_typing.rst b/tutorials/scripting/gdscript/static_typing.rst index b7065ddd058..931aeacceed 100644 --- a/tutorials/scripting/gdscript/static_typing.rst +++ b/tutorials/scripting/gdscript/static_typing.rst @@ -230,6 +230,35 @@ For instance, you can write:: The array will remain untyped, but the ``name`` variable within the ``for`` loop will always be of ``String`` type. +Specify the element type of a ``Dictionary`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To define the type of a ``Dictionary``'s keys and values, enclose the type name in ``[]`` +and separate the key and value type with a comma. + +A dictionary's value type applies to ``for`` loop variables, as well as some operators like +``[]`` and ``[]=``. Dictionary methods that return values and other operators +(such as ``==``) are still untyped. Built-in types, native and custom classes, +and enums may be used as element types. Nested typed collections +(like ``Dictionary[String, Dictionary[String, int]]``) are not supported. + + +:: + + var fruit_costs: Dictionary[String, int] = { "apple": 5, "orange": 10 } + var vehicles: Dictionary[String, Node] = { "car": $Car, "plane": $Plane } + var item_tiles: Dictionary[Vector2i, Item] = { Vector2i(0, 0): Item.new(), Vector2i(0, 1): Item.new() } + var dictionary_of_dictionaries: Dictionary[String, Dictionary] = { { } } + # var dicts: Dictionary[String, Dictionary[String, int]] -- disallowed + + for cost in fruit_costs: + # cost has type `int` + + # The following would be errors: + fruit_costs["pear"] += vehicles + var s: String = fruit_costs["apple"] + fruit_costs["orange"] = "lots" + Type casting ~~~~~~~~~~~~