为什么Crystal无法解析1+1的赋值类型?
Why can't Crystal resolve the type of the assignment of 1 + 1?
为什么Crystal不能t/won解析this的类型? (我看到文档没有提到编译器可以推断实例方法调用,但它背后的基本原理是什么,尤其是当只涉及 stdlib 函数时?编译时间?)
class Something
def blah
@result = 1 + 1
end
end
Something.new().blah
编译器错误:
Showing last frame. Use --error-trace for full trace.
error in line 3
Error: can't infer the type of instance variable '@result' of SomeObject
The type of a instance variable, if not declared explicitly with
`@result : Type`, is inferred from assignments to it across
the whole program.
The assignments must look like this:
1. `@result = 1` (or other literals), inferred to the literal's type
2. `@result = Type.new`, type is inferred to be Type
3. `@result = Type.method`, where `method` has a return type
annotation, type is inferred from it
4. `@result = arg`, with 'arg' being a method argument with a
type restriction 'Type', type is inferred to be Type
5. `@result = arg`, with 'arg' being a method argument with a
default value, type is inferred using rules 1, 2 and 3 from it
6. `@result = uninitialized Type`, type is inferred to be Type
7. `@result = LibSome.func`, and `LibSome` is a `lib`, type
is inferred from that fun.
8. `LibSome.func(out @result)`, and `LibSome` is a `lib`, type
is inferred from that fun argument.
Other assignments have no effect on its type.
can't infer the type of instance variable '@result' of SomeObject
如果我没记错的话,Crystal 过去在推导类型时更积极。虽然它在某些示例中很优雅,但在更大的项目中会产生更多问题。编译时间成为一个问题(增量编译很难或不可能),当一切传播时,代码中的错误(例如,由于打字错误)可能更难追踪。
最后,保持干扰规则更简单并回退到表达式的显式类型被认为更实用。这是 2015 年的 discussion about the change。我没有参与语言设计,但通过线程阅读,我认为线程中的参数适用于你的问题(为什么 1 + 1
需要明确输入).请注意,1 + 1
是一个简单的情况,但是一旦允许,表达式可以变得任意复杂。通常,编译器必须遍历整个程序代码才能进行分析。
为什么Crystal不能t/won解析this的类型? (我看到文档没有提到编译器可以推断实例方法调用,但它背后的基本原理是什么,尤其是当只涉及 stdlib 函数时?编译时间?)
class Something
def blah
@result = 1 + 1
end
end
Something.new().blah
编译器错误:
Showing last frame. Use --error-trace for full trace.
error in line 3
Error: can't infer the type of instance variable '@result' of SomeObject
The type of a instance variable, if not declared explicitly with
`@result : Type`, is inferred from assignments to it across
the whole program.
The assignments must look like this:
1. `@result = 1` (or other literals), inferred to the literal's type
2. `@result = Type.new`, type is inferred to be Type
3. `@result = Type.method`, where `method` has a return type
annotation, type is inferred from it
4. `@result = arg`, with 'arg' being a method argument with a
type restriction 'Type', type is inferred to be Type
5. `@result = arg`, with 'arg' being a method argument with a
default value, type is inferred using rules 1, 2 and 3 from it
6. `@result = uninitialized Type`, type is inferred to be Type
7. `@result = LibSome.func`, and `LibSome` is a `lib`, type
is inferred from that fun.
8. `LibSome.func(out @result)`, and `LibSome` is a `lib`, type
is inferred from that fun argument.
Other assignments have no effect on its type.
can't infer the type of instance variable '@result' of SomeObject
如果我没记错的话,Crystal 过去在推导类型时更积极。虽然它在某些示例中很优雅,但在更大的项目中会产生更多问题。编译时间成为一个问题(增量编译很难或不可能),当一切传播时,代码中的错误(例如,由于打字错误)可能更难追踪。
最后,保持干扰规则更简单并回退到表达式的显式类型被认为更实用。这是 2015 年的 discussion about the change。我没有参与语言设计,但通过线程阅读,我认为线程中的参数适用于你的问题(为什么 1 + 1
需要明确输入).请注意,1 + 1
是一个简单的情况,但是一旦允许,表达式可以变得任意复杂。通常,编译器必须遍历整个程序代码才能进行分析。