Dictionary
包含键值对的内置数据结构。
描述
字典是关系容器,包含的值(Value)由唯一的键(Key)引用。添加新条目时,字典会保持插入顺序。在其他编程语言中,这种数据结构有时也称为哈希表或关联数组。
在大括号 {} 中放置用逗号分隔的一对对 键: 值 列表就可以定义字典。
字典的创建:
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 分隔语法。
# 不需要在键周围加引号,但键名只能为字符串常量。
# 另外,键名必须以字母或下划线开头。
# 此处的 `some_key` 是字符串字面量,不是变量!
another_dict = {
some_key = 42,
}
var myDict = new Godot.Collections.Dictionary(); // 创建空字典。
var pointsDict = new Godot.Collections.Dictionary
{
{ "White", 50 },
{ "Yellow", 75 },
{ "Orange", 100 },
};
你可以通过键来访问字典中对应的值。上面的例子中,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():
# 不能使用点语法,因为 `my_color` 是变量。
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] # 将 Array 赋给 String 键。
}
var myDict = new Godot.Collections.Dictionary
{
{ "First Array", new Godot.Collections.Array { 1, 2, 3, 4 } }
};
要往已有字典中添加键,请像已有键一样进行访问并赋值:
var points_dict = { "White": 50, "Yellow": 75, "Orange": 100 }
points_dict["Blue"] = 150 # 将 "Blue" 添加为键,并将 150 赋为它的值。
var pointsDict = new Godot.Collections.Dictionary
{
{ "White", 50 },
{ "Yellow", 75 },
{ "Orange", 100 },
};
pointsDict["Blue"] = 150; // 将 "Blue" 添加为键,并将 150 赋为它的值。
最后,对于非类型化的字典而言,同一个字典里可以包含不同类型的键和值:
# 这是有效的字典。
# 要访问下面的 "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" } } },
};
字典中的键可以用 for 关键字进行遍历:
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` 为键,`amount` 为值。
}
创建类型化字典可以强制键和值所使用的类型。类型化字典只能够包含给定类型的键和值,也可以是继承自给定类的类型。
# 创建类型化字典,使用 String 键和 int 值。
# 尝试使用其他类型的键或值会报错。
var typed_dict: Dictionary[String, int] = {
"some_key": 1,
"some_other_key": 2,
}
# 创建类型化字典,使用 String 键和任意类型的值。
# 尝试使用其他类型的键会报错。
var typed_dict_key_only: Dictionary[String, Variant] = {
"some_key": 12.34,
"some_other_key": "string",
}
// 创建类型化字典,使用 String 键和 int 值。
// 尝试使用其他类型的键或值会报错。
var typedDict = new Godot.Collections.Dictionary<String, int> {
{"some_key", 1},
{"some_other_key", 2},
};
// 创建类型化字典,使用 String 键和任意类型的值。
// 尝试使用其他类型的键会报错。
var typedDictKeyOnly = new Godot.Collections.Dictionary<String, Variant> {
{"some_key", 12.34},
{"some_other_key", "string"},
};
注意:字典始终按引用传递。要获取字典的副本,能独立于原字典进行修改,请使用 duplicate()。
注意:不支持在遍历字典时清除元素,可能造成无法预知的行为。
备注
通过 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 🔗
Duplicates this dictionary, deeply, like duplicate() when passing true, with extra control over how subresources are handled.
deep_subresources_mode must be one of the values from DeepDuplicateMode. By default, only internal resources will be duplicated (recursively).
如果字典中存在与键对应的条目,则将其移除。如果给定的键 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。
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()。