• 可转换关系

    可转换关系

    类型 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) 也是左值。