RtW

5 March 2026


Nix: Атрибутный набор

В языке Nix attrset (сокращение от attribute set) — это самый важный и фундаментальный тип данных. Если говорить максимально просто: это словарь (или хэш-таблица), в котором ключи сопоставляются со значениями.

Это «кирпичик», из которого строится вся конфигурация NixOS.

Как это выглядит в коде

Набор атрибутов всегда заключается в фигурные скобки { }. Внутри вы перечисляете пары «ключ = значение», разделяя их точкой с запятой:

{
  имя = "Мой компьютер";
  ядра = 8;
  активен = true;
}

Основные характеристики attrset

Неупорядоченность
В отличие от списка, порядок записей внутри не имеет значения. Система просто ищет нужный ключ по имени.
Вложенность
Наборы могут содержать другие наборы. Именно так строится иерархия настроек в configuration.nix:
{
  networking = {
    hostName = "nixos";
    wireless.enable = true;
  };
}

Здесь networking — это атрибут, значением которого является другой атрибутный набор.

Доступ через точку
Чтобы получить данные из набора, используется синтаксис с точкой. mySet.имя вернет "Мой компьютер".
Уникальность ключей
Внутри одного набора все имена ключей должны быть уникальны.

Почему NixOS целиком состоит из attrset?

Вся конфигурация вашей системы — это один гигантский вложенный атрибутный набор. Когда вы пишете

{
  services.xserver.enable = true;
}

вы на самом деле работаете с такими сущностями:

  1. Корневой атрибутный набор (вся ваша конфигурация).
  2. В нем есть ключ services, значением которого является другой набор.
  3. Внутри набора services есть ключ xserver, который содержит еще один набор.
  4. В нем есть ключ enable, которому вы присваиваете логическое значение true.

Аналогия для понимания

Представьте себе структуру папок и файлов на диске. Папка — это атрибутный набор, а файл внутри нее — это значение. Вы можете создать папку etc, в ней создать папку nixos, а в ней — файл configuration.nix. В языке Nix это выглядит точно так же:

  • Папка = { ... }
  • Имя файла = ключ
  • Содержимое файла = значение

Когда Nix начинает собирать вашу систему, он проходит по всем этим «папкам» (наборам атрибутов), объединяет их, вычисляет значения и на выходе создает готовое дерево «файлов» для операционной системы. Именно поэтому понимание attrset — это 90% успеха в освоении NixOS.

Разница между набором данных и модулем

В языке Nix конфигурация — это дерево атрибутов. Однако NixOS делает шаг дальше, превращая эту структуру в систему модулей. Чтобы понять, почему сигнатура { config, pkgs, ... }: критически важна, нужно разделить два состояния файла.

1. Файл как обычный набор данных

Если вы напишете код просто так, без функции,

{
  networking.hostName = "nixos";
}

то для интерпретатора Nix это просто статичный объект (набор данных). Он не знает ничего о «внешнем мире». В этом контексте:

  • Вы не можете обратиться к pkgs, потому что у этого объекта нет доступа к контексту всей системы.
  • Система не понимает, что этот код должен быть интегрирован в основной процесс сборки.
  • Это превращается в «слепую» структуру, которая не может динамически менять свои свойства в зависимости от других настроек системы.

2. Файл как динамический модуль

Добавляя сигнатуру { config, pkgs, lib, ... }: перед кодом, вы превращаете файл в анонимную функцию.

{ config, pkgs, lib, ... }:

{
  # Содержимое модуля
}

Роль оператора :

Оператор : указывает, что после этого знака начинается тело функции, в которой вы пишете настройки вашей системы.

По сути, это объявление того, что ваш файл является функцией, которой нужны эти инструменты для работы.

Когда NixOS загружает вашу конфигурацию, происходит процесс, похожий на инъекцию зависимостей в программировании:

  1. Функция как интерфейс: Система видит, что ваш файл — это функция. Она смотрит, какие аргументы вы запросили (например, pkgs).
  2. Исполнение в контексте: NixOS вызывает эту функцию и подставляет в неё реальные значения pkgs (библиотеку пакетов всей системы) и config (итоговое дерево конфигурации системы, вычисляемое лениво, по надобности).
  3. Доступ к ресурсам: Именно благодаря этому механизму внутри функции вы можете писать pkgs.firefox или lib.mkIf. Без сигнатуры у вас нет «каналов связи» с остальной системой, и Nix не знает, где искать определения этих команд.

Почему это важно для NixOS

В NixOS тысячи опций связаны между собой. Модуль — это динамическая единица, которая может:

  • Считывать настройки из других файлов через config.
  • Использовать системные ресурсы через pkgs.
  • Определять поведение системы условно, например: «Если включен графический интерфейс, установи этот пакет, иначе — нет».

Без обертки в функцию ваш файл остается изолированным набором значений, который не может участвовать в этом общем процессе обмена данными. Добавление сигнатуры открывает модулю доступ ко всему «движку» NixOS.

Creative Commons License This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Created by Y.E.T.If you see an error, please report it.