【问题标题】:Nix maintain original order of a setNix 保持原组顺序
【发布时间】:2026-01-29 22:30:01
【问题描述】:

假设:
您在运行 NixOS 或某些 Linux 发行版的操作系统上安装了 yqnix

问题:
nix 可以保持 set 的原始顺序吗?即如果我创建一个 sample.nix 文件:

{pkgs}:
let
dockerComposeConfig = {
    version = "1.0";
    services = {
        srv1 = { name = "srv1"; };
        srv2 = { name = "srv2"; };
    };
};
in writeTextFile {
    name = "docker-compose.json";
    text = builtins.toJSON dockerComposeConfig;

}

当我在下面构建并将输出转换为 yaml 时,我注意到该集合已按 Nix 字母顺序排列。是否有一种解决方法可以使我的 JSON 保持与 Docker 用户预期的顺序相同,以便 `dockerComposeConfig 属性保持其创建顺序?

# Cmd1
nix-build -E "with import <nixpkgs> {}; callPackage ./sample.nix {}"

# Cmd2
cat /nix/store/SOMEHASH-docker-compose.json | yq r - --prettyPrint

【问题讨论】:

标签: docker docker-compose nix yq


【解决方案1】:

Nix 属性集对其属性没有排序,它们在内存中表示为排序数组。规范化值有助于重现性。

如果它真的很重要,您可以编写一个函数,将键值对列表转换为 JSON 对象作为 Nix 字符串。但这不会像builtins.toJSON 那样容易使用。我会将 JSON 视为“编译后的构建输出”,而不必太担心美学。

旁注:从语义上讲,它们甚至没有按任何顺序创建。 Nix 语言是声明性的:Nix 表达式(不包括派生)描述的东西是真实的,而不是如何创建它,尽管它可以用函数来定义。 这是 Nix 的懒惰有效的必要条件。

【讨论】: