可转换关系

类型 a隐式 转换到类型 b 如果下列算法返回真:

  1. proc isImplicitlyConvertible(a, b: PType): bool =
  2. if isSubtype(a, b) or isCovariant(a, b):
  3. return true
  4. case a.kind
  5. of int: result = b in {int8, int16, int32, int64, uint, uint8, uint16,
  6. uint32, uint64, float, float32, float64}
  7. of int8: result = b in {int16, int32, int64, int}
  8. of int16: result = b in {int32, int64, int}
  9. of int32: result = b in {int64, int}
  10. of uint: result = b in {uint32, uint64}
  11. of uint8: result = b in {uint16, uint32, uint64}
  12. of uint16: result = b in {uint32, uint64}
  13. of uint32: result = b in {uint64}
  14. of float: result = b in {float32, float64}
  15. of float32: result = b in {float64, float}
  16. of float64: result = b in {float32, float}
  17. of seq:
  18. result = b == openArray and typeEquals(a.baseType, b.baseType)
  19. of array:
  20. result = b == openArray and typeEquals(a.baseType, b.baseType)
  21. if a.baseType == char and a.indexType.rangeA == 0:
  22. result = b == cstring
  23. of cstring, ptr:
  24. result = b == pointer
  25. of string:
  26. result = b == cstring

Nim为 范围 类型构造函数执行了隐式转换。

a0, b0 为类型 T.

A = range[a0..b0] 为实参类型, F 正式的形参类型。 从 AF 存在隐式转换,如果 a0 >= low(F) 且 b0 <= high(F)TF 是有符号或无符号整型。

如果以下算法返回true,则类型 a显式 转换为类型 b

  1. proc isIntegralType(t: PType): bool =
  2. result = isOrdinal(t) or t.kind in {float, float32, float64}
  3.  
  4. proc isExplicitlyConvertible(a, b: PType): bool =
  5. result = false
  6. if isImplicitlyConvertible(a, b): return true
  7. if typeEqualsOrDistinct(a, b): return true
  8. if isIntegralType(a) and isIntegralType(b): return true
  9. if isSubtype(a, b) or isSubtype(b, a): return true

可转换关系可以通过用户定义的类型 converter 来放宽。

  1. converter toInt(x: char): int = result = ord(x)
  2.  
  3. var
  4. x: int
  5. chr: char = 'a'
  6.  
  7. # 隐式转换发生在这里
  8. x = chr
  9. echo x # => 97
  10. # 你也可以使用显式转换
  11. x = chr.toInt
  12. echo x # => 97

如果 a 是左值并且 typeEqualsOrDistinct(T, type(a)) 成立, 类型转换 T(a) 也是左值。