Crystal如何创建Struct/类的对象数组 复刻Go结构体数组实现
Crystal 基于 Struct 创建对象数组的正确方法
核心错误点
之前的写法存在两个核心问题:
- 数组类型声明错误:
[] of Int32 | String表示数组只能存储整数或字符串,无法存放Book类型的实例。 - 错误拆分实例:Class版本中自定义的
object方法返回的是包含四个字段的元组,不是Book实例本身,和声明的数组元素类型不匹配。
正确实现(对齐Go代码逻辑)
Crystal中struct是值类型,和Go的struct语义完全一致,不需要改成class就能实现预期效果,可直接参考以下代码:
# 定义Book结构体,和Go struct行为一致(值传递、拷贝传值) struct Book # Crystal惯例实例变量用小写蛇形命名,大写开头为常量 def initialize( @id : Int32, @title : String, @author : String, @desc : String ) end # 生成字段读访问器,方便外部读取属性 getter :id, :title, :author, :desc end # 数组类型直接指定为Book,完全对应Go的[]models.Book声明 books = [] of Book # 追加Book实例到数组 book1 = Book.new(1, "Hello", "Me", "This is a test.") books << book1 # 也可以在初始化数组时直接填充元素,和Go的字面量初始化效果一致 books_go_style = [ Book.new( id: 1, title: "Golang", author: "Gopher", desc: "A book for Go" ) ] of Book # 测试输出 puts books puts books_go_style
关键规则说明
- 数组类型声明:数组要存储什么类型的元素,
[] of后直接写对应类型名即可,不需要枚举类型内部的字段类型。存储Book实例就写[] of Book,存储字符串就写[] of String。 - 不要拆分实例存储:直接把结构体/类的实例存入数组即可,不需要手动把实例字段拆成元组或者哈希再存,否则会丢失类型信息,也不符合结构体的使用逻辑。
- Struct和Class的选择:
- 纯数据结构、需要值传递语义(和Go struct一致)选
struct - 需要引用传递、多态、继承的场景选
class
- 纯数据结构、需要值传递语义(和Go struct一致)选
- 命名规范:Crystal中实例变量、方法名统一使用小写蛇形命名,大写开头的标识符会被解析为常量,虽然语法上不会直接报错,但不符合语言惯例,容易引发难以排查的问题。
内容的提问来源于stack exchange,提问作者learncodes123
相关产品推荐
相关产品推荐

