问题描述
为什么我可以在 Crystal 中定义这样的方法:
def foo(bar): String
bar.to_json
end
foo({"x" => 1,"y" => 2})
但是这种类型推断不适用于类:
class Foo
def initialize(bar)
@bar = bar
end
def foo: String
@bar.to_json
end
end
Foo.new({"x" => 1,"y" => 2}).foo
它以
结束Error: can't infer the type of instance variable '@bar' of Foo
我遗漏了 Crystal 的类型推断什么?对此有什么解决方法?
解决方法
基于类的等效方法是使类成为泛型:
require "json"
class Foo(T)
def initialize(@bar : T)
end
def foo
@bar.to_json
end
end
puts Foo.new({"x" => 1,"y" => 2}).foo
实例变量需要以一种或另一种方式设置它们的类型,因为字典类型流分析要困难得多,因此对它们做起来更慢。类也构建了你的程序的基础,所以尽可能窄地输入它们不仅使编译器的工作更容易,也使它们更容易使用。对实例变量的类型限制过于开放会导致错误消息很长且令人困惑。
您可以在引入更改以要求对实例变量进行类型注释的原始提案中阅读更多内容:https://github.com/crystal-lang/crystal/issues/2390