Crystal语言中如何创建复合类型元素构成的数组?
问题根因
你的代码类型不匹配:定义的Type别名中Array(Output)约束数组成员必须是Output类的实例,但你传入的hash.raw类型是String | Array(Output) | Hash(Symbol, Output)联合类型,并非Output实例,不符合类型校验规则。
实现方案
根据你的业务设计需求,二选一即可:
方案1:保留原有类型定义,直接传入Output实例
如果你的设计是所有嵌套节点都用Output类包装,不需要暴露内部raw值的直接嵌套,直接把Output实例放入数组即可,不需要提前取raw属性:
class Output alias Type = String | Array(Output) | Hash(Symbol, Output) getter raw def initialize(@raw : Type) end end hash = Output.new({ :a => Output.new("1") }) # 直接传入Output实例,符合Array(Output)的类型约束 array = Output.new([hash])
这种写法适合需要给Output类扩展自定义方法(比如格式化输出、节点遍历等)的场景,所有节点都是统一的Output类型,调用方法时不需要额外做类型判断。
方案2:调整递归类型定义,支持raw值直接嵌套
如果你希望数组、哈希中可以直接存字符串、嵌套数组、嵌套哈希这些原始值,不需要额外套Output包装,把类型别名改成递归自引用的结构即可:
class Output # 递归定义Type,容器内存储的是Type本身而非Output实例 alias Type = String | Array(Type) | Hash(Symbol, Type) getter raw def initialize(@raw : Type) end end hash = Output.new({ :a => Output.new("1").raw }) array = Output.new([hash.raw])
这种写法没有额外包装层,序列化、跨方法传值时更轻便,适合仅用Output做简单数据封装、不需要给节点扩展业务方法的场景。
内容的提问来源于stack exchange,提问作者Dorian
相关产品推荐
相关产品推荐

