类型自动转换¶
Crystal 在没有歧义的情况下透明地转换某些类型的元素。
数字自动转换¶
如果不会丢失精度,数值类型的数值会自动转换为更大的数值类型。
def foo(x : Int32) : Int32
x
end
def bar(x : Float32) : Float32
x
end
def bar64(x : Float64) : Float64
x
end
foo 0xFFFF_u16 # OK, an UInt16 always fit an Int32
foo 0xFFFF_u64 # OK, this particular UInt64 fit in an Int32
bar(foo 1) # Fails, casting an Int32 to a Float32 might lose precision
bar64(bar 1) # OK, a Float32 can be autocasted to a Float64
即使数字字面量的类型不同,只要字面量的实际值适合目标类型,数字字面量也会被始终转换。
表达式会被转换(就像上面的最后一个示例一样),除非将标志 `no_number_autocast` 传递给编译器(请参阅 编译器特性)。
如果存在歧义,例如,因为存在多个选项,编译器会抛出错误。
def foo(x : Int64)
x
end
def foo(x : Int128)
x
end
foo 1_i32 # Error: ambiguous call, implicit cast of Int32 matches all of Int64, Int128
目前,自动转换仅在两种情况下起作用:在函数调用时(如前面所示)以及在类/实例变量初始化时。以下示例展示了实例变量的两种情况:在初始化时进行转换有效,但在赋值时则无效。
class Foo
@x : Int64 = 10 # OK, 10 fits in an Int64
def set_x(y)
@x = y
end
end
Foo.new.set_x 1 # Error: "at line 5: instance variable '@x' of Foo must be Int64, not Int32"
符号自动转换¶
符号会自动转换为枚举成员,从而能够更简洁地编写它们。
enum TwoValues
A
B
end
def foo(v : TwoValues)
case v
in TwoValues::A
p "A"
in TwoValues::B
p "B"
end
end
foo :a # autocasted to TwoValues::A