Почему грязное внедрение необходимо даже для кода в области видимости шаблона?
Пожалуйста, примите во внимание следующее:
import options
template tpl[T](a: untyped) : Option[T] =
var b {.inject.}: T = 4
a
none(int)
discard
tpl[int]:
echo b
Это создает и запускает и приводит к выводу:
4
Но если вы удалите {.inject.}
Прагма, вы получаете:
... шаблон / общий экземпляр отсюда
Ошибка: необъявленный идентификатор: 'b'
Я не думаю, что мы можем рассмотреть блок кода echo b
чужд "внутренностям" шаблона, поскольку: он используется только в расширенном составе шаблона, и: он передается в качестве аргумента, а не используется снаружи.
Я вынужден использовать что-то грязное, и теперь я испортил свой глобальный охват, чтобы заставить это работать?
2 ответа
То, как это работает, имеет смысл. Вы хотите быть явно о том, что доступно внутри кода, указанного пользователем.
Вы можете сохранить свою глобальную область гигиены с помощью block
:
import options
template tpl[T](a: untyped) : Option[T] =
block:
var b {.inject.}: T = 4
a
none(int)
discard
tpl[int]:
echo b
Причина заключается в том, что внедренные имена являются частью открытого интерфейса шаблона. Вы не хотите, чтобы детали реализации шаблона просочились внутрь пользовательского кода и, возможно, создали там конфликты имен, поэтому все переменные, созданные внутри шаблона, по умолчанию скрыты от пользовательского кода.
С помощью inject
как это не считается грязным, это то, что нужно делать здесь.