如何在Godot中将全局枚举值转换为字符串?

8

"GlobalScope" 类定义了许多基本的枚举,如 Error 枚举。

当出现错误时,我试图生成有意义的日志。然而,仅打印 Error 类型的值只会打印整数,这并不是很有帮助。

Godot 关于 枚举 的文档表明查找该值应该像字典一样工作。然而,尝试访问 Error[error_value] 会出现错误:

The identifier "Error" isn't declared in the current scope.

如何将这样的枚举值转换为字符串?
3个回答

3
在您参考的文档中,它解释道枚举基本上只是创建一些常量:
enum {TILE_BRICK, TILE_FLOOR, TILE_SPIKE, TILE_TELEPORT}
# Is the same as:
const TILE_BRICK = 0
const TILE_FLOOR = 1
const TILE_SPIKE = 2
const TILE_TELEPORT = 3

不过,这些常量的标识符名称仅存在于代码中方便人类阅读。在运行时,它们会被替换为机器可用的内容,并且以后无法访问。如果我想打印标识符名称,就必须手动执行:

# Manually print TILE_FLOOR's name as a string, then its value.
print("The value of TILE_FLOOR is ", TILE_FLOOR)

因此,如果您的目标是具有描述性错误输出,您应该以类似的方式进行,例如:

if unexpected_bug_found:
    # Manually print the error description, then actually return the value.
    print("ERR_BUG: There was a unexpected bug!")
    return ERR_BUG

与字典的关系在于,可以使字典像枚举一样运作,反之不行。枚举只能是一个带有整数赋值的标识符列表,而字典也可以做到这一点。但是它们还可以做其他很酷的事情,例如拥有字符串标识符,我相信您可能一直在思考这个:

const MyDict = {
    NORMAL_KEY = 0,
    'STRING_KEY' : 1, # uses a colon instead of equals sign
}
func _ready():
    print("MyDict.NORMAL_KEY is ",    MyDict.NORMAL_KEY)    # valid
    print("MyDict.STRING_KEY is ",    MyDict.STRING_KEY)    # valid
    print("MyDict[NORMAL_KEY] is ",   MyDict[NORMAL_KEY])   # INVALID
    print("MyDict['STRING_KEY'] is ", MyDict['STRING_KEY']) # valid
    # Dictionary['KEY'] only works if the key is a string.

虽然这种方法有用,但即使在这种情况下,我们也假设已经手动获取到了与标识符名称匹配的字符串,因此我们可以像第一个示例一样手动打印该字符串。


1

我曾经采用的幼稚方法是在一个单例中实现,在一个包含很多staticfunc的文件中(由class_name引用)。

static func get_error(global_error_constant:int) -> String:
    var info := Engine.get_version_info()
    var version := "%s.%s" % [info.major, info.minor]
    var default := ["OK","FAILED","ERR_UNAVAILABLE","ERR_UNCONFIGURED","ERR_UNAUTHORIZED","ERR_PARAMETER_RANGE_ERROR","ERR_OUT_OF_MEMORY","ERR_FILE_NOT_FOUND","ERR_FILE_BAD_DRIVE","ERR_FILE_BAD_PATH","ERR_FILE_NO_PERMISSION","ERR_FILE_ALREADY_IN_USE","ERR_FILE_CANT_OPEN","ERR_FILE_CANT_WRITE","ERR_FILE_CANT_READ","ERR_FILE_UNRECOGNIZED","ERR_FILE_CORRUPT","ERR_FILE_MISSING_DEPENDENCIES","ERR_FILE_EOF","ERR_CANT_OPEN","ERR_CANT_CREATE","ERR_QUERY_FAILED","ERR_ALREADY_IN_USE","ERR_LOCKED","ERR_TIMEOUT","ERR_CANT_CONNECT","ERR_CANT_RESOLVE","ERR_CONNECTION_ERROR","ERR_CANT_ACQUIRE_RESOURCE","ERR_CANT_FORK","ERR_INVALID_DATA","ERR_INVALID_PARAMETER","ERR_ALREADY_EXISTS","ERR_DOES_NOT_EXIST","ERR_DATABASE_CANT_READ","ERR_DATABASE_CANT_WRITE","ERR_COMPILATION_FAILED","ERR_METHOD_NOT_FOUND","ERR_LINK_FAILED","ERR_SCRIPT_FAILED","ERR_CYCLIC_LINK","ERR_INVALID_DECLARATION","ERR_DUPLICATE_SYMBOL","ERR_PARSE_ERROR","ERR_BUSY","ERR_SKIP","ERR_HELP","ERR_BUG","ERR_PRINTER_ON_FIR"]
    match version:
        "3.4":
            return default[global_error_constant]
    # Regexp to use on @GlobalScope documentation
    # \s+=\s+.+  replace by nothing
    # (\w+)\s+ replace by "$1", (with quotes and comma)
    printerr("you must check and add %s version in get_error()" % version)
    return default[global_error_constant]

所以 print(MyClass.get_error(err)) 或者 assert(!err, MyClass.get_error(err)) 都很方便。

对于非全局的情况,我做了这个,虽然这不是你的问题,但它与此高度相关。

能够访问@GlobalScope@GDScript将会很有用,也许是由于内存成本?

static func get_enum_flags(_class:String, _enum:String, flags:int) -> PoolStringArray:
    var ret := PoolStringArray()
    var enum_flags := ClassDB.class_get_enum_constants(_class, _enum)
    for i in enum_flags.size():
        if (1 << i) & flags:
            ret.append(enum_flags[i])
    return ret


static func get_constant_or_enum(_class:String, number:int, _enum:="") -> String:
    if _enum:
        return ClassDB.class_get_enum_constants(_class, _enum)[number]
    return ClassDB.class_get_integer_constant_list(_class)[number]

0

GDScript处理@GlobalScope.Error枚举的方式让我感到困惑,但对于其他枚举,你可以像这样提取枚举值的名称...

enum_type.keys()[enum_value]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接