@TaskLocal: контекст, который едет по дереву задач 📍
🎯 @TaskLocal (SE-0311, Swift 5.5) — значение, привязанное к области видимости: всё, что запускается внутри, его видит. Идеально для request ID, трейсинга, метаданных логирования, чтобы не таскать параметр через каждый вызов.
⚠️ Главная путаница здесь работает в обратную сторону от того, как обычно думают. Дочерние задачи в TaskGroupи async let наследуют значение — это ожидаемо. Но и обычный неструктурированный Task { } тоже наследует: значения копируются в момент создания. Теряет привязку только Task.detached { }.
Пара технических деталей: свойство обязано быть static, тип обязан быть Sendable, а Optional не требуется — @TaskLocal static var x: Int = 0 вполне легально. Никакого nonisolated(unsafe) не нужно: TaskLocal — это final class, конформящий Sendable, поэтому static var здесь не вызывает ошибку про глобальное изменяемое состояние.
💡 И про цену: чтение task-local дороже обычного статического свойства — это доступ к thread-local плюс проход по стеку привязок вверх по цепочке родительских задач. Из горячих циклов чтение стоит выносить.