可转换关系
类型 a 可 隐式 转换到类型 b 如果下列算法返回真:
- proc isImplicitlyConvertible(a, b: PType): bool =
- if isSubtype(a, b) or isCovariant(a, b):
- return true
- case a.kind
- of int: result = b in {int8, int16, int32, int64, uint, uint8, uint16,
- uint32, uint64, float, float32, float64}
- of int8: result = b in {int16, int32, int64, int}
- of int16: result = b in {int32, int64, int}
- of int32: result = b in {int64, int}
- of uint: result = b in {uint32, uint64}
- of uint8: result = b in {uint16, uint32, uint64}
- of uint16: result = b in {uint32, uint64}
- of uint32: result = b in {uint64}
- of float: result = b in {float32, float64}
- of float32: result = b in {float64, float}
- of float64: result = b in {float32, float}
- of seq:
- result = b == openArray and typeEquals(a.baseType, b.baseType)
- of array:
- result = b == openArray and typeEquals(a.baseType, b.baseType)
- if a.baseType == char and a.indexType.rangeA == 0:
- result = b == cstring
- of cstring, ptr:
- result = b == pointer
- of string:
- result = b == cstring
Nim为 范围 类型构造函数执行了隐式转换。
设 a0, b0 为类型 T.
设 A = range[a0..b0] 为实参类型, F 正式的形参类型。 从 A 到 F 存在隐式转换,如果 a0 >= low(F) 且 b0 <= high(F) 且 T 各 F 是有符号或无符号整型。
如果以下算法返回true,则类型 a 可 显式 转换为类型 b :
- proc isIntegralType(t: PType): bool =
- result = isOrdinal(t) or t.kind in {float, float32, float64}
- proc isExplicitlyConvertible(a, b: PType): bool =
- result = false
- if isImplicitlyConvertible(a, b): return true
- if typeEqualsOrDistinct(a, b): return true
- if isIntegralType(a) and isIntegralType(b): return true
- if isSubtype(a, b) or isSubtype(b, a): return true
可转换关系可以通过用户定义的类型 converter 来放宽。
- converter toInt(x: char): int = result = ord(x)
- var
- x: int
- chr: char = 'a'
- # 隐式转换发生在这里
- x = chr
- echo x # => 97
- # 你也可以使用显式转换
- x = chr.toInt
- echo x # => 97
如果 a 是左值并且 typeEqualsOrDistinct(T, type(a)) 成立, 类型转换 T(a) 也是左值。