首页 > 解决方案 > 为什么 Crystal 无法推断实例变量的类型?

问题描述

为什么此代码对实例变量失败?

a = 4.days # Works
class A
  @a = 4.days # Fails
end

附言

未来有没有改进的计划?似乎是很常见和有用的东西。

标签: crystal-lang

解决方案


@a = 4会像文字一样工作,但它4是一个表达式,因此不能自动推导出来。出于同样的原因,还需要显式类型,即使不需要。4.days@a = 1 + 1 @a = 2

关于未来的计划,有趣的是该功能存在,但被有意删除。

简而言之,原因是为了保持编译步骤简单。自动归纳类型很优雅,但也有缺点:

  • 编译速度较慢
  • 为错误类型的程序生成好的错误消息变得很困难
  • 重用以前的编译结果变得困难(或不可能?)

原因是,通常,您必须分析整个源代码中的函数调用链。请注意,并非所有表达式都像1 + 1. Even4.days已经有些复杂了,因为编译器需要推断days方法调用的返回类型。

如果您想了解有关设计决策的更多信息,我建议您阅读2015 年的讨论

你可能会问,为什么它适用于课外的第一个作业?我假设在这种情况下,上下文更加本地化。因此,反对允许它的论点并不完全适用。例如,如果您更改函数内的语句,其效果并不像更改类的布局那样全局。

同样,这是一个权衡。但是在这两种情况下强制类型都会极大地改变体验。虽然在类的上下文中效果相当小,但强制任何赋值的显式类型会将“类 Ruby”Crystal 语言变成传统的类型化语言,其中每个赋值都需要显式类型化。


推荐阅读