You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Crystal如何创建Struct/类的对象数组 复刻Go结构体数组实现

Crystal 基于 Struct 创建对象数组的正确方法

核心错误点

之前的写法存在两个核心问题:

  1. 数组类型声明错误:[] of Int32 | String表示数组只能存储整数或字符串,无法存放Book类型的实例。
  2. 错误拆分实例: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
  • 命名规范:Crystal中实例变量、方法名统一使用小写蛇形命名,大写开头的标识符会被解析为常量,虽然语法上不会直接报错,但不符合语言惯例,容易引发难以排查的问题。

内容的提问来源于stack exchange,提问作者learncodes123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 03:03:22