Menu
CoddyTech

类中的枚举

本课属于 Coddy GDScript 学习旅程的“面向对象编程”单元。第 44 课,共 65 课。

可以在类中、变量旁边声明枚举。这样,这些选项就属于该类:

# weapon.gd
class_name Weapon
extends RefCounted

enum Kind { SWORD, BOW, STAFF }

var kind: Kind

func _init(weapon_kind: Kind) -> void:
	kind = weapon_kind

func is_ranged() -> bool:
	return kind == Kind.BOW or kind == Kind.STAFF

在 weapon.gd 中,枚举是 Kind。其他文件都先写类名,再写 Weapon.Kind.BOW,无论是在值、类型注释还是 match 模式中:

# blacksmith.gd
class_name Blacksmith
extends RefCounted

static func repair_cost(kind: Weapon.Kind) -> int:
	match kind:
		Weapon.Kind.SWORD:
			return 20
		Weapon.Kind.BOW:
			return 15
	return 30

这些选项仍然是数字:Weapon.new(Weapon.Kind.BOW).kind会打印1。枚举本身的作用类似于一个将名称映射到数字的字典:

print(Weapon.Kind.keys())       # ["SWORD", "BOW", "STAFF"]
print(Weapon.Kind.find_key(1))  # BOW
print(Weapon.Kind["STAFF"])     # 2
print(Weapon.Kind.size())       # 3
for kind in Weapon.Kind.values():
	print(Weapon.Kind.find_key(kind), ": ", Blacksmith.repair_cost(kind))

循环会打印 SWORD: 20、BOW: 15 和 STAFF: 30。GDScript 不会检查数字是否属于这些选项之一:Weapon.new(7) 会创建一个 kind 为 7 的武器。传入这些具名选项,代码就能保持正确。

描述某个类的枚举应放在该类内部,这样读者就能看出 Kind 在 Weapon.Kind.BOW 中的来源。

challenge icon

挑战

简单

使用定义在 Potion 类中的枚举来整理药水。

  • 在 potion.gd 中声明 enum Kind { HEAL, MANA, POISON },并将 kind 的类型设为 Kind。
  • Potion.from_text(text, strength) 是一个静态函数,它会将 "MANA" 转换为 Kind.MANA,并返回一瓶新药水。
  • describe() 会使用类型名称和强度,返回 HEAL potion: +20 HP、MANA potion: +15 MP 或 POISON potion: -5 HP。
  • 在 belt.gd 中,summary() 会按枚举中的顺序,为每种类型返回一行:HEAL: 2 (35 total),其中包含该类型的药水数量,以及括号中的强度总和。即使某种类型没有药水,也会显示一行。

提供的代码会读取后续药水的数量(HEAL 20),将每瓶药水添加到腰带中,打印药水描述,然后打印摘要。输入 HEAL 20、POISON 5、HEAL 15 时,会打印:

Added HEAL potion: +20 HP
Added POISON potion: -5 HP
Added HEAL potion: +15 HP
HEAL: 2 (35 total)
MANA: 0 (0 total)
POISON: 1 (5 total)

你的代码应写在 potion.gd 和 belt.gd 中。main.gd 包含提供的输入/输出代码,不能编辑。

亲手试试

extends Node

func _ready():
	# 提供的输入输出代码:保持原样。
	var belt := Belt.new()
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		var potion := Potion.from_text(parts[0], int(parts[1]))
		belt.add(potion)
		print("Added ", potion.describe())
	for line in belt.summary():
		print(line)
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: GDScript 在线编译器