typedesc.txt 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. Special Types
  2. =============
  3. static[T]
  4. ---------
  5. **Note**: static[T] is still in development.
  6. As their name suggests, static parameters must be known at compile-time:
  7. .. code-block:: nim
  8. proc precompiledRegex(pattern: static[string]): RegEx =
  9. var res {.global.} = re(pattern)
  10. return res
  11. precompiledRegex("/d+") # Replaces the call with a precompiled
  12. # regex, stored in a global variable
  13. precompiledRegex(paramStr(1)) # Error, command-line options
  14. # are not known at compile-time
  15. For the purposes of code generation, all static params are treated as
  16. generic params - the proc will be compiled separately for each unique
  17. supplied value (or combination of values).
  18. Static params can also appear in the signatures of generic types:
  19. .. code-block:: nim
  20. type
  21. Matrix[M,N: static[int]; T: Number] = array[0..(M*N - 1), T]
  22. # Note how `Number` is just a type constraint here, while
  23. # `static[int]` requires us to supply a compile-time int value
  24. AffineTransform2D[T] = Matrix[3, 3, T]
  25. AffineTransform3D[T] = Matrix[4, 4, T]
  26. var m1: AffineTransform3D[float] # OK
  27. var m2: AffineTransform2D[string] # Error, `string` is not a `Number`
  28. typedesc
  29. --------
  30. `typedesc` is a special type allowing one to treat types as compile-time values
  31. (i.e. if types are compile-time values and all values have a type, then
  32. typedesc must be their type).
  33. When used as a regular proc param, typedesc acts as a type class. The proc
  34. will be instantiated for each unique type parameter and one can refer to the
  35. instantiation type using the param name:
  36. .. code-block:: nim
  37. proc new(T: typedesc): ref T =
  38. echo "allocating ", T.name
  39. new(result)
  40. var n = Node.new
  41. var tree = new(BinaryTree[int])
  42. When multiple typedesc params are present, they act like a distinct type class
  43. (i.e. they will bind freely to different types). To force a bind-once behavior
  44. one can use a named alias or an explicit `typedesc` generic param:
  45. .. code-block:: nim
  46. proc acceptOnlyTypePairs[T: typedesc, U: typedesc](A, B: T; C, D: U)
  47. Once bound, typedesc params can appear in the rest of the proc signature:
  48. .. code-block:: nim
  49. template declareVariableWithType(T: typedesc, value: T) =
  50. var x: T = value
  51. declareVariableWithType int, 42
  52. Overload resolution can be further influenced by constraining the set of
  53. types that will match the typedesc param:
  54. .. code-block:: nim
  55. template maxval(T: typedesc[int]): int = high(int)
  56. template maxval(T: typedesc[float]): float = Inf
  57. var i = int.maxval
  58. var f = float.maxval
  59. var s = string.maxval # error, maxval is not implemented for string
  60. The constraint can be a concrete type or a type class.