Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Dictionary
包含键值对的内置数据结构。
描述
字典是一种关联容器,它里面包含的数值都可以通过唯一的“键”(key)来引用。当添加新的条目时,字典会保留它们的插入顺序。在其他编程语言中,这种数据结构通常被称为哈希映射(hash map)或关联数组(associative array)。
你可以通过在大括号 {} 里放置一个由逗号分隔的 键: 值(key: value)对列表来定义一个字典。
创建一个字典:
var my_dict = {} # 创建一个空字典。
var dict_variable_key = "Another key name"
var dict_variable_value = "value2"
var another_dict = {
"Some key name": "value1",
dict_variable_key: dict_variable_value,
}
var points_dict = { "White": 50, "Yellow": 75, "Orange": 100 }
# 另一种 Lua 风格的语法。
# 这种写法不需要在键(key)的周围加引号,但键名只能使用字符串常量。
# 此外,键名必须以字母或下划线开头。
# 在这里,some_key 是一个字符串字面量,而不是一个变量哦!
another_dict = {
some_key = 42,
}
var myDict = new Godot.Collections.Dictionary(); // Creates an empty dictionary.
var pointsDict = new Godot.Collections.Dictionary
{
{ "White", 50 },
{ "Yellow", 75 },
{ "Orange", 100 },
};
你可以通过引用字典中对应的键(key),来获取它的值(value)。在上面的例子中,points_dict["White"] 会返回 50。你也可以写成 points_dict.White,两者的效果是完全一样的。 不过,如果你用来访问字典的键不是一个固定的字符串(比如是一个数字或者变量),那你就必须使用中括号(````)的语法了。
@export_enum("White", "Yellow", "Orange") var my_color: String
var points_dict = { "White": 50, "Yellow": 75, "Orange": 100 }
func _ready():
# We can't use dot syntax here as `my_color` is a variable.
var points = points_dict[my_color]
[Export(PropertyHint.Enum, "White,Yellow,Orange")]
public string MyColor { get; set; }
private Godot.Collections.Dictionary _pointsDict = new Godot.Collections.Dictionary
{
{ "White", 50 },
{ "Yellow", 75 },
{ "Orange", 100 },
};
public override void _Ready()
{
int points = (int)_pointsDict[MyColor];
}
在上面的代码中,points 将会被赋予与 my_color 中选中的颜色相对应的那个值。
字典里也可以包含更复杂的数据:
var my_dict = {
"First Array": [1, 2, 3, 4] # Assigns an Array to a String key.
}
var myDict = new Godot.Collections.Dictionary
{
{ "First Array", new Godot.Collections.Array { 1, 2, 3, 4 } }
};
To add a key to an existing dictionary, access it like an existing key and assign to it:
var points_dict = { "White": 50, "Yellow": 75, "Orange": 100 }
points_dict["Blue"] = 150 # Add "Blue" as a key and assign 150 as its value.
var pointsDict = new Godot.Collections.Dictionary
{
{ "White", 50 },
{ "Yellow", 75 },
{ "Orange", 100 },
};
pointsDict["Blue"] = 150; // Add "Blue" as a key and assign 150 as its value.
最后,未指定类型的字典可以在同一个字典里包含不同类型的键和值。
# 这是一个有效的字典。
# 如果想要获取下面嵌套的字符串 "Nested value",你可以使用 my_dict.sub_dict.sub_key 或者 my_dict["sub_dict"]["sub_key"]。
# 这两种索引(取值)风格可以根据你的需要随意混搭使用哦。
var my_dict = {
"String Key": 5,
4: [1, 2, 3],
7: "Hello",
"sub_dict": { "sub_key": "Nested value" },
}
// 这是一个有效的字典。
// 想要获取下面嵌套的字符串 "Nested value",请使用 ((Godot.Collections.Dictionary)myDict["sub_dict"])["sub_key"]。
var myDict = new Godot.Collections.Dictionary {
{ "String Key", 5 },
{ 4, new Godot.Collections.Array { 1, 2, 3 } },
{ 7, "Hello" },
{ "sub_dict", new Godot.Collections.Dictionary { { "sub_key", "Nested value" } } },
};
The keys of a dictionary can be iterated with the for keyword:
var groceries = { "Orange": 20, "Apple": 2, "Banana": 4 }
for fruit in groceries:
var amount = groceries[fruit]
var groceries = new Godot.Collections.Dictionary { { "Orange", 20 }, { "Apple", 2 }, { "Banana", 4 } };
foreach (var (fruit, amount) in groceries)
{
// `fruit` is the key, `amount` is the value.
}
为了强制规定键(key)和值(value)的类型,你可以创建一个类型化字典(typed dictionary)。类型化字典只能包含指定类型的键和值,或者包含继承自指定类的键和值:
# 创建一个键(key)为字符串类型、值(value)为整数类型的类型化字典。
# 如果尝试使用任何其他类型的键或值,都会导致报错。
var typed_dict: Dictionary[String, int] = {
"some_key": 1,
"some_other_key": 2,
}
# 创建一个键(key)为字符串类型、值(value)为任意类型的类型化字典。
# 如果尝试使用任何其他类型的键,都会导致报错。
var typed_dict_key_only: Dictionary[String, Variant] = {
"some_key": 12.34,
"some_other_key": "string",
}
// 创建一个键(key)为字符串类型、值(value)为整数类型的类型化字典。
// 如果尝试使用任何其他类型的键或值,都会导致报错。
var typedDict = new Godot.Collections.Dictionary<String, int> {
{"some_key", 1},
{"some_other_key", 2},
};
// 创建一个键(key)为字符串类型、值(value)为任意类型的类型化字典。
// 如果尝试使用任何其他类型的键,都会导致报错。
var typedDictKeyOnly = new Godot.Collections.Dictionary<String, Variant> {
{"some_key", 12.34},
{"some_other_key", "string"},
};
注意: 字典总是通过引用传递的。如果你想获取一个字典的副本,以便在不影响原字典的情况下独立修改它,请使用 duplicate() 方法。
注意: 在遍历字典的过程中,不支持删除(擦除)其中的元素,这样做会导致不可预测的行为(比如程序出错或逻辑混乱)。
注意: 在布尔值判断中,如果字典是空的({}),它的值会被判定为 false;除此之外,任何非空的字典都会被判定为 true。
备注
通过 C# 使用该 API 时会有显著不同,详见 C# API 与 GDScript 的差异。
教程
构造函数
Dictionary(base: Dictionary, key_type: int, key_class_name: StringName, key_script: Variant, value_type: int, value_class_name: StringName, value_script: Variant) |
|
Dictionary(from: Dictionary) |
方法
void |
assign(dictionary: Dictionary) |
void |
clear() |
duplicate_deep(deep_subresources_mode: int = 1) const |
|
get_or_add(key: Variant, default: Variant = null) |
|
get_typed_key_builtin() const |
|
get_typed_key_class_name() const |
|
get_typed_key_script() const |
|
get_typed_value_builtin() const |
|
get_typed_value_class_name() const |
|
get_typed_value_script() const |
|
hash() const |
|
is_empty() const |
|
is_read_only() const |
|
is_same_typed(dictionary: Dictionary) const |
|
is_same_typed_key(dictionary: Dictionary) const |
|
is_same_typed_value(dictionary: Dictionary) const |
|
is_typed() const |
|
is_typed_key() const |
|
is_typed_value() const |
|
keys() const |
|
void |
|
void |
merge(dictionary: Dictionary, overwrite: bool = false) |
merged(dictionary: Dictionary, overwrite: bool = false) const |
|
recursive_equal(dictionary: Dictionary, recursion_count: int) const |
|
size() const |
|
void |
sort() |
values() const |
运算符
operator !=(right: Dictionary) |
|
operator ==(right: Dictionary) |
|
operator [](key: Variant) |
构造函数说明
Dictionary Dictionary() 🔗
构造空的 Dictionary。
Dictionary Dictionary(base: Dictionary, key_type: int, key_class_name: StringName, key_script: Variant, value_type: int, value_class_name: StringName, value_script: Variant)
根据 base 字典创建类型化字典。类型化字典只能包含给定类型的键和值,也可以是继承自给定的类,由该构造函数的参数描述。
Dictionary Dictionary(from: Dictionary)
返回与 from 相同的字典。如果你需要该字典的副本,请使用 duplicate()。
方法说明
void assign(dictionary: Dictionary) 🔗
将其他 dictionary 中的元素赋值给该字典中。字典的大小会调整到与 dictionary 一致。如果为类型化字典则会执行类型转换。
void clear() 🔗
清空该字典,移除其中的所有条目。
Dictionary duplicate(deep: bool = false) const 🔗
返回字典的新副本。
默认情况下返回的是浅拷贝:嵌套的 Array、Dictionary 和 Resource 键和值与原字典共享。对这些键和值的修改会影响另一个字典。
如果 deep 为 true 则会返回深拷贝:嵌套的数组和字典也会进行(递归的)复制。不过 Resource 仍然是和原字典共享的。
Dictionary duplicate_deep(deep_subresources_mode: int = 1) const 🔗
深度复制该字典,类似于传递 true 时的 duplicate() 方法,但可以额外控制子资源的处理方式。
deep_subresources_mode 必须是 DeepDuplicateMode 中的某个值。默认只会(递归)复制内部资源。
如果字典中存在与键对应的条目,则将其移除。如果给定的键 key 在字典中存在,则返回 true ,否则返回 false 。
注意:请勿在遍历字典时擦除条目。你可以改为遍历 keys() 数组。
Variant find_key(value: Variant) const 🔗
找到并返回关联值等于 value 的第一个键,如果没有找到,则返回 null。
注意:null 也是有效的键。如果字典中包含这个键,则 find_key() 可能会给出误导性的结果。
Variant get(key: Variant, default: Variant = null) const 🔗
返回字典中给定 key(键)所对应的值。如果该 key 不存在,则返回 default(默认值);如果省略了默认值参数,则返回 null。
注意: 如果 default 参数的计算成本很高,或者会产生不必要的副作用,建议改用 has() 方法来判断:
# Always calls `expensive_function()`.
dict.get("key", expensive_function())
# Calls `expensive_function()` only if the key does not exist.
dict.get("key") if dict.has("key") else expensive_function()
Variant get_or_add(key: Variant, default: Variant = null) 🔗
获取一个值并确保设置了键。如果 key 存在于字典中,则其行为类似于 get()。否则,default 值将被插入到字典中并返回。
int get_typed_key_builtin() const 🔗
将类型化字典中键的内置 Variant 类型以 Variant.Type 常量的形式返回。如果键不是类型化的,则返回 @GlobalScope.TYPE_NIL。另见 is_typed_key()。
StringName get_typed_key_class_name() const 🔗
如果类型化字典的键的内置 Variant 类型为 @GlobalScope.TYPE_OBJECT 则返回其内置类名。否则返回空 StringName。另见 is_typed_key() 和 Object.get_class()。
Variant get_typed_key_script() const 🔗
返回与类型化字典的键相关联的 Script 实例,如果不存在则返回 null。另见 is_typed_key()。
int get_typed_value_builtin() const 🔗
将类型化字典中值的内置 Variant 类型以 Variant.Type 常量的形式返回。如果值不是类型化的,则返回 @GlobalScope.TYPE_NIL。另见 is_typed_value()。
StringName get_typed_value_class_name() const 🔗
如果类型化字典的值的内置 Variant 类型为 @GlobalScope.TYPE_OBJECT 则返回其内置类名。否则返回空 StringName。另见 is_typed_value() 和 Object.get_class()。
Variant get_typed_value_script() const 🔗
返回与类型化字典的值相关联的 Script 实例,如果不存在则返回 null。另见 is_typed_value()。
bool has(key: Variant) const 🔗
如果该字典包含给定的键 key,则返回 true。
var my_dict = {
"Godot" : 4,
210 : null,
}
print(my_dict.has("Godot")) # 输出 true
print(my_dict.has(210)) # 输出 true
print(my_dict.has(4)) # 输出 false
var myDict = new Godot.Collections.Dictionary
{
{ "Godot", 4 },
{ 210, default },
};
GD.Print(myDict.ContainsKey("Godot")); // 输出 True
GD.Print(myDict.ContainsKey(210)); // 输出 True
GD.Print(myDict.ContainsKey(4)); // 输出 False
在 GDScript 中等价于 in 运算符:
if "Godot" in { "Godot": 4 }:
print("这个键存在!") # 会进行输出。
注意:只要键 key 存在,该方法就会返回 true,即便这个键对应的值为 null。
bool has_all(keys: Array) const 🔗
如果该字典包含给定数组 keys 中的所有键,则返回 true。
var data = { "width": 10, "height": 20 }
data.has_all(["height", "width"]) # 返回 true
返回代表该字典内容的 32 位整数哈希值。
var dict1 = { "A": 10, "B": 2 }
var dict2 = { "A": 10, "B": 2 }
print(dict1.hash() == dict2.hash()) # 输出 true
var dict1 = new Godot.Collections.Dictionary { { "A", 10 }, { "B", 2 } };
var dict2 = new Godot.Collections.Dictionary { { "A", 10 }, { "B", 2 } };
// Godot.Collections.Dictionary 没有 Hash() 方法。请改用 GD.Hash()。
GD.Print(GD.Hash(dict1) == GD.Hash(dict2)); // 输出 True
注意:如果两个字典条目相同,但顺序不同,则哈希值也不同。
注意:哈希值相同的字典不保证相同,因为可能存在哈希碰撞。相对地,哈希值不同的字典保证不同。
如果该字典为空(大小为 0),则返回 true。另见 size()。
如果该字典是只读的,则返回 true 。见 make_read_only()。用 const 关键字声明的字典自动只读。
bool is_same_typed(dictionary: Dictionary) const 🔗
如果该字典与 dictionary 的类型相同,则返回 true 。
bool is_same_typed_key(dictionary: Dictionary) const 🔗
如果该字典的键与 dictionary 的键的类型相同,则返回 true 。
bool is_same_typed_value(dictionary: Dictionary) const 🔗
如果该字典的值与 dictionary 的值的类型相同,则返回 true 。
如果该字典为类型化字典则返回 true。类型化字典只能存储关联类型的键和值,能够为 [] 运算符提供类型安全。类型化字典的方法返回的仍然是 Variant。
如果字典的键有类型约束,则返回 true。
如果字典的值有类型约束,则返回 true。
返回该字典中的键列表。
void make_read_only() 🔗
使该字典只读,即禁用字典内容的修改。不适用于嵌套内容,例如内嵌字典的内容。
void merge(dictionary: Dictionary, overwrite: bool = false) 🔗
将 dictionary 中的条目添加到该字典中。默认情况下,不会复制重复的键,除非 overwrite 为 true。
var dict = { "item": "sword", "quantity": 2 }
var other_dict = { "quantity": 15, "color": "silver" }
# 默认情况下禁用覆盖已有键。
dict.merge(other_dict)
print(dict) # { "item": "sword", "quantity": 2, "color": "silver" }
# 启用覆盖已有键。
dict.merge(other_dict, true)
print(dict) # { "item": "sword", "quantity": 15, "color": "silver" }
var dict = new Godot.Collections.Dictionary
{
["item"] = "sword",
["quantity"] = 2,
};
var otherDict = new Godot.Collections.Dictionary
{
["quantity"] = 15,
["color"] = "silver",
};
// 默认情况下禁用覆盖已有键。
dict.Merge(otherDict);
GD.Print(dict); // { "item": "sword", "quantity": 2, "color": "silver" }
// 启用覆盖已有键。
dict.Merge(otherDict, true);
GD.Print(dict); // { "item": "sword", "quantity": 15, "color": "silver" }
注意:merge() 不是递归的。嵌套的字典是否可被视为键可以被覆盖,具体取决于 overwrite 的值,但它们永远不会被合并在一起。
Dictionary merged(dictionary: Dictionary, overwrite: bool = false) const 🔗
返回该字典与 dictionary 合并后的副本。默认情况下不会复制重复的键,除非 overwrite 为 true。另见 merge()。
该方法可以使用默认值快速制作字典:
var base = { "fruit": "apple", "vegetable": "potato" }
var extra = { "fruit": "orange", "dressing": "vinegar" }
# 输出 { "fruit": "orange", "vegetable": "potato", "dressing": "vinegar" }
print(extra.merged(base))
# 输出 { "fruit": "apple", "vegetable": "potato", "dressing": "vinegar" }
print(extra.merged(base, true))
bool recursive_equal(dictionary: Dictionary, recursion_count: int) const 🔗
如果两个字典包含相同的键和值,则返回 true,内部的 Dictionary 和 Array 的键和值将进行递归比较。
bool set(key: Variant, value: Variant) 🔗
将给定 key 对应元素的值设置为指定的 value。若设置成功则返回 true。若字典为只读,或 key 与 value 的类型与字典类型不匹配,则操作失败并返回 false。此方法等同于使用 [] 运算符(即 dict[key] = value)。
返回该字典中条目的数量。空字典({ })始终返回 0。另见 is_empty()。
void sort() 🔗
将字典中的键按升序排列。最终的顺序取决于键与键之间的“小于”比较(<)。
var numbers = { "c": 2, "a": 0, "b": 1 }
numbers.sort()
print(numbers) # Prints { "a": 0, "b": 1, "c": 2 }
该方法能够确保字典中条目顺序的一致性,适用于调用 keys() 或 values() 的情况,以及通过 @GlobalScope.str() 或 JSON.stringify() 将字典转换为字符串的情况。
返回该字典中的值列表。
运算符说明
bool operator !=(right: Dictionary) 🔗
如果两个字典包含的键、值不同,则返回 true 。
bool operator ==(right: Dictionary) 🔗
如果两个字典包含的键、值心相同,则返回 true 。条目顺序并不重要。
注意:在 C# 中,按照惯例,这个运算符进行的是按引用比较。如果你需要按值比较,请遍历这两个字典。
Variant operator [](key: Variant) 🔗
返回该字典中与给定的键 key 对应的值。如果条目不存在,失败并返回 null。为了更安全的访问,请使用 get() 或 has()。