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

无法推断Document实例变量@id的类型,ViewModel初始化报错求助

解决无法推断Document实例变量@id类型的问题

这个错误的核心原因是类型不匹配加上Crystal的静态类型检查机制:你的DatabaseModel中id是Int类型,但Document的@id声明为Int64,直接赋值时编译器无法确定类型转换的安全性,导致推断失败。另外我们也需要确保JSON.mapping的写法符合Crystal规范,避免额外的类型歧义。

下面是具体的解决方案:

方案1:统一类型(推荐)

如果数据库中的ID字段实际类型是Int64,直接修改DatabaseModel的ID类型,保持和Document一致:

class DatabaseModel < ActiveRecord::Model
  @@connection_pool_capacity = 25
  @@connection_pool_timeout = 0.03
  adapter postgres
  table_name database_model
  primary id : Int64  # 将Int改为Int64,与Document的@id类型统一
  field name : String
  # ...其他字段
end

这样Document初始化方法中直接赋值就不会有类型冲突,编译器能顺利推断@id的类型。

方案2:显式类型转换(无法修改DatabaseModel时使用)

如果必须保留DatabaseModel的id为Int,在初始化时显式将db_model.id转换为Int64,给编译器明确的类型提示:

class Document
  @id : Int64
  @name : String

  JSON.mapping(
    id: Int64,
    name: String,
  )

  def initialize(db_model)
    @id = db_model.id.to_i64  # 显式转换为Int64,消除类型歧义
    @name = db_model.name
  end
end

显式转换会告诉编译器这里的类型变化,直接解决推断失败的问题。

额外优化:规范JSON.mapping写法

虽然你的JSON.mapping写法在旧版Crystal中可行,但新版更推荐使用键值对形式明确指定类型,让代码更清晰,也能帮助编译器更好解析类型信息:

JSON.mapping(
  id: {type: Int64},
  name: {type: String}
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:37:18