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
相关产品推荐
相关产品推荐

