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

Crystal报错Crystal::ClassDef#resolved_type cannot be nil含义及解决

问题解答

错误含义

Crystal::ClassDef#resolved_type cannot be nil (NilAssertionError) 这个错误表示:在宏处理流程中,编译器尝试获取Routes类的已解析类型(resolved_type)时,发现该值为空。根源是你在get宏内部重新打开Routes类的写法,导致Crystal宏解析上下文无法正确关联到已定义的Routes类元信息,进而触发空断言错误。

正确的方法定义方式

无需在宏里重新打开Routes类,直接在宏内部给Routes定义类方法即可。这样编译器能正确识别方法所属类,不会触发类型解析的空错误,同时满足返回"/"的需求。

修正后的核心代码

class Routes
  getter routes
 
  def initialize
    @routes = [] of Route
  end
  
  macro get(route, mapping)
    route = Route.new({{route}}) do |context|
      {{mapping.receiver}}.new.{{mapping.name}}
    end
    
    # 直接定义类方法,无需重新打开类
    def self.{{mapping.id.underscore.gsub(/\./, "__")}}
      "/"
    end
    
    Main.routes.routes << route
  end
end

完整可运行代码

require "http"

class Routes
  getter routes
 
  def initialize
    @routes = [] of Route
  end
  
  macro get(route, mapping)
    route = Route.new({{route}}) do |context|
      {{mapping.receiver}}.new.{{mapping.name}}
    end
    
    def self.{{mapping.id.underscore.gsub(/\./, "__")}}
      "/"
    end
    
    Main.routes.routes << route
  end
end

Routes.new.draw do
  get "/", HomeController.show
end
 
class Main
  @@routes : Routes = Routes.new
 
  def self.routes
    @@routes
  end
 
  def self.routes=(value)
    @@routes = value
  end
end
 
class HomeController
  def show
    "this is show"
  end
end
 
class Route
  getter path
  getter callback
 
  def initialize(@path : String, &@callback : HTTP::Server::Context -> String)
  end
end

# 测试调用类方法
pp Routes.home_controller__show # 输出 "/"

你的解决方法生效原因

你后续的代码将get宏直接放在Routes类内部定义,并且用def self.xxx的方式声明类方法,让宏的上下文直接归属Routes类,编译器能正确解析类的元信息,不会出现resolved_type为空的情况,因此错误被解决。

内容的提问来源于stack exchange,提问作者Hári János

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:07:46