【问题标题】:How to convert global enum values to string in Godot?如何将全局枚举值转换为 Godot 中的字符串?
【发布时间】:2020-09-11 00:35:32
【问题描述】:

“GlobalScope”类定义了许多基本枚举,例如 Error 枚举。

我正在尝试在发生错误时生成有意义的日志。但是打印Error 类型的值只会打印整数,这不是很有帮助。

enums 上的 Godot 文档指出,查找值应该像时尚的字典一样工作。但是,尝试访问 Error[error_value] 时出现以下错误:

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

如何将这些枚举值转换为字符串?

【问题讨论】:

    标签: enums godot


    【解决方案1】:

    在您引用的文档中,它解释了枚举基本上只是创建了一堆常量:

    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.
    

    这以它自己的方式很有用,但即使在这种情况下,我们假设已经有字符串与标识符名称显式匹配,这意味着我们也可以像第一个示例一样手动打印该字符串。

    【讨论】:

      【解决方案2】:

      我为我做的天真的方法,在一个 Singleton 中(实际上在一个包含很多 staticfuncs 的文件中,由 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]
      

      【讨论】:

        猜你喜欢
        • 2022-01-10
        • 1970-01-01
        • 2016-07-30
        • 1970-01-01
        • 2013-07-03
        • 1970-01-01
        • 2018-11-09
        • 1970-01-01
        相关资源
        最近更新 更多