Spec-Zone.ru › Nim

std/typetraits

ИсточникРедактировать

Этот модуль определяет процедуры рефлексии времени компиляции для работы с типами.

Нестабильный API.

Пример:

import std/typetraits
type A = enum a0 = 2, a1 = 4, a2
type B = enum b0 = 2, b1, b2
assert A is enum
assert A is HoleyEnum
assert A isnot OrdinalEnum
assert B isnot HoleyEnum
assert B is OrdinalEnum
assert int isnot HoleyEnum
type C[T] = enum h0 = 2, h1 = 4
assert C[float] is HoleyEnum

Импорты

since, макросы

Типы

HoleyEnum = (not Ordinal) and enum
Перечисление с дырами. Источник Редактировать
OrdinalEnum = Ordinal and enum
Перечисление без дыр. Источник Редактировать
StaticParam[value] = object
Используется для обертывания статического значения в genericParams. Источник Редактировать

Процедуры

proc arity(t: typedesc): int {.magic: "TypeTrait", ...raises: [], tags: [],
                               forbids: [].}
Возвращает арность t. Это количество компонентов "тип" или количество параметров обобщения данного типа t.

Пример:

doAssert arity(int) == 0
doAssert arity(seq[string]) == 1
doAssert arity(array[3, int]) == 2
doAssert arity((int, int, float, string)) == 4
Источник Редактировать
proc distinctBase(T: typedesc; recursive: static bool = true): typedesc {.
    magic: "TypeTrait", ...raises: [], tags: [], forbids: [].}

Возвращает базовый тип для различных типов или сам тип в противном случае. Если recursive равно false, возвращается только непосредственный базовый тип.

См. также:

  • шаблон distinctBase

Пример:

type MyInt = distinct int
type MyOtherInt = distinct MyInt
doAssert distinctBase(MyInt) is int
doAssert distinctBase(MyOtherInt) is int
doAssert distinctBase(MyOtherInt, false) is MyInt
doAssert distinctBase(int) is int
Источник Редактировать
proc genericHead(t: typedesc): typedesc {.magic: "TypeTrait", ...raises: [],
    tags: [], forbids: [].}

Принимает экземпляризованный обобщенный тип и возвращает его неэкземпляризованную форму. Если предоставленный тип не является обобщенным, будет выведено сообщение об ошибке времени компиляции.

См. также:

  • процедура stripGenericParams

Пример:

type
  Foo[T] = object
  FooInst = Foo[int]
  Foo2 = genericHead(FooInst)

doAssert Foo2 is Foo and Foo is Foo2
doAssert genericHead(Foo[seq[string]]) is Foo
doAssert not compiles(genericHead(int))

type Generic = concept f
  type _ = genericHead(typeof(f))

proc bar(a: Generic): typeof(a) = a

doAssert bar(Foo[string].default) == Foo[string]()
doAssert not compiles bar(string.default)

when false: # these don't work yet
  doAssert genericHead(Foo[int])[float] is Foo[float]
  doAssert seq[int].genericHead is seq
Источник Редактировать
proc hasClosure(fn: NimNode): bool {....raises: [], tags: [], forbids: [].}
Возвращает true, если func/proc/etc fn имеет closure. fn должен быть разрешенным символом типа nnkSym. Это подразумевает, что макрос, вызывающий эту процедуру, должен принимать аргументы typed и не должен принимать аргументы untyped. Источник Редактировать
proc hasDefaultValue(t: typedesc): bool {.magic: "TypeTrait", ...raises: [],
    tags: [], forbids: [].}
Возвращает true, если t имеет допустимое значение по умолчанию.

Пример:

{.experimental: "strictNotNil".}
type
  NilableObject = ref object
    a: int
  Object = NilableObject not nil
  RequiresInit[T] = object
    a {.requiresInit.}: T

assert hasDefaultValue(NilableObject)
assert not hasDefaultValue(Object)
assert hasDefaultValue(string)
assert not hasDefaultValue(var string)
assert not hasDefaultValue(RequiresInit[int])
Источник Редактировать
proc isNamedTuple(T: typedesc): bool {.magic: "TypeTrait", ...raises: [], tags: [],
                                       forbids: [].}
Возвращает true для именованных кортежей, false для любого другого типа.

Пример:

doAssert not isNamedTuple(int)
doAssert not isNamedTuple((string, int))
doAssert isNamedTuple(tuple[name: string, age: int])
Источник Редактировать
proc name(t: typedesc): string {.magic: "TypeTrait", ...raises: [], tags: [],
                                 forbids: [].}

Возвращает имя t.

Псевдоним для system.`$`(t) с Nim v0.20.

Пример:

doAssert name(int) == "int"
doAssert name(seq[string]) == "seq[string]"
Источник Редактировать
proc rangeBase(T: typedesc[range]): typedesc {.magic: "TypeTrait", ...raises: [],
    tags: [], forbids: [].}

Возвращает базовый тип для диапазонов или сам тип в противном случае.

См. также:

  • шаблон rangeBase

Пример:

type MyRange = range[0..5]
type MyEnum = enum a, b, c
type MyEnumRange = range[b..c]
doAssert rangeBase(MyRange) is int
doAssert rangeBase(MyEnumRange) is MyEnum
doAssert rangeBase(range['a'..'z']) is char
Источник Редактировать
proc stripGenericParams(t: typedesc): typedesc {.magic: "TypeTrait", ...raises: [],
    tags: [], forbids: [].}
Этот признак похож на genericHead, но вместо создания ошибки для необобщенных типов, он просто вернет их без изменений.

Пример:

type Foo[T] = object

doAssert stripGenericParams(Foo[string]) is Foo
doAssert stripGenericParams(int) is int
Источник Редактировать
proc supportsCopyMem(t: typedesc): bool {.magic: "TypeTrait", ...raises: [],
    tags: [], forbids: [].}

Возвращает true, если t безопасно использовать для copyMem.

Другие языки называют такой тип blob.

Источник Редактировать
proc tupleLen(T: typedesc[tuple]): int {.magic: "TypeTrait", ...raises: [],
    tags: [], forbids: [].}

Возвращает количество элементов кортежа типа T.

См. также:

  • шаблон tupleLen

Пример:

doAssert tupleLen((int, int, float, string)) == 4
doAssert tupleLen(tuple[name: string, age: int]) == 2
Источник Редактировать

Макросы

macro enumLen(T: typedesc[enum]): int
Возвращает количество элементов в перечислении T.

Пример:

type Foo = enum
  fooItem1
  fooItem2

doAssert Foo.enumLen == 2
Источник Редактировать

Шаблоны

template distinctBase[T](a: T; recursive: static bool = true): untyped
Перегрузка distinctBase для значений.

Пример:

type MyInt = distinct int
type MyOtherInt = distinct MyInt
doAssert 12.MyInt.distinctBase == 12
doAssert 12.MyOtherInt.distinctBase == 12
doAssert 12.MyOtherInt.distinctBase(false) is MyInt
doAssert 12.distinctBase == 12
Исходный код Изменить
template elementType(a: untyped): typedesc
Возвращает тип элемента a, который может быть любым итерируемым объектом (по которому можно итерироваться).

Пример:

iterator myiter(n: int): auto =
  for i in 0 ..< n:
    yield i

doAssert elementType(@[1,2]) is int
doAssert elementType("asdf") is char
doAssert elementType(myiter(3)) is int
Исходный код Изменить
template genericParams(T: typedesc): untyped

Возвращает кортеж универсальных параметров для универсального типа T.

Примечание: Для встроенного типа массива параметр индекса всегда станет типом диапазона после привязки к переменной.

Пример:

type Foo[T1, T2] = object

doAssert genericParams(Foo[float, string]) is (float, string)

type Bar[N: static float, T] = object

doAssert genericParams(Bar[1.0, string]) is (StaticParam[1.0], string)
doAssert genericParams(Bar[1.0, string]).get(0).value == 1.0
doAssert genericParams(seq[Bar[2.0, string]]).get(0) is Bar[2.0, string]
var s: seq[Bar[3.0, string]]
doAssert genericParams(typeof(s)) is (Bar[3.0, string],)

doAssert genericParams(array[10, int]) is (StaticParam[10], int)
var a: array[10, int]
doAssert genericParams(typeof(a)) is (range[0..9], int)
Исходный код Изменить
template get(T: typedesc[tuple]; i: static int): untyped
Возвращает i-й элемент T.

Пример:

doAssert get((int, int, float, string), 2) is float
Исходный код Изменить
template pointerBase[T](_: typedesc[ptr T | ref T]): typedesc
Возвращает T для ref T | ptr T.

Пример:

assert (ref int).pointerBase is int
type A = ptr seq[float]
assert A.pointerBase is seq[float]
assert (ref A).pointerBase is A # not seq[float]
assert (var s = "abc"; s[0].addr).typeof.pointerBase is char
Исходный код Изменить
template rangeBase[T: range](a: T): untyped
Перегрузка rangeBase для значений.

Пример:

type MyRange = range[0..5]
type MyEnum = enum a, b, c
type MyEnumRange = range[b..c]
let x = MyRange(3)
doAssert rangeBase(x) is int
doAssert $typeof(rangeBase(x)) == "int"
doAssert rangeBase(x) == 3
let y: set[MyEnumRange] = {c}
for e in y:
  doAssert rangeBase(e) is MyEnum
  doAssert $typeof(rangeBase(e)) == "MyEnum"
  doAssert rangeBase(e) == c
let z: seq[range['a'..'z']] = @['c']
doAssert rangeBase(z[0]) is char
doAssert $typeof(rangeBase(z[0])) == "char"
doAssert rangeBase(z[0]) == 'c'
Исходный код Изменить
template toSigned(T: typedesc[SomeInteger and not range]): untyped
Возвращает знаковый тип с тем же размером в битах, что и T.

Пример:

assert int8.toSigned is int8
assert uint16.toSigned is int16
# range types are currently unsupported:
assert not compiles(toSigned(range[0..7]))
Исходный код Изменить
template toUnsigned(T: typedesc[SomeInteger and not range]): untyped
Возвращает беззнаковый тип с тем же размером в битах, что и T.

Пример:

assert int8.toUnsigned is uint8
assert uint.toUnsigned is uint
assert int.toUnsigned is uint
# range types are currently unsupported:
assert not compiles(toUnsigned(range[0..7]))
Исходный код Изменить
template tupleLen(t: tuple): int

Возвращает количество элементов кортежа t.

См. также:

  • tupleLen proc

Пример:

doAssert tupleLen((1, 2)) == 2
Исходный код Изменить

© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/typetraits.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API