无法理解 Nix 表达式中的语句

Trouble Understanding With Statement in Nix Expression

来自Section 12.5 of Nix Pills

Finish the expression for graphviz with gd support (note the use of the with expression in buildInputs to avoid repeating pkgs):

let
  pkgs = import <nixpkgs> {};
  mkDerivation = import ./autotools.nix pkgs;
in mkDerivation {
  name = "graphviz";
  src = ./graphviz-2.38.0.tar.gz;
  buildInputs = with pkgs; [ gd fontconfig libjpeg bzip2 ];
}

问题:为什么buildInputs中的代码片段末尾需要with pkgs?我认为 pkgs 已经通过顶部的 let 绑定在范围内?

是的,pkgs 在范围内,但这不会自动将其属性放入范围。

pkgs 是一个包含 gdfontconfig 等属性的 Nix 集...如果您删除 with pkgs,那么 buildInputs 的列表将无法解析上述属性。使用您的示例,以下两个表达式在语义上是相同的:

buildInputs = with pkgs; [ gd fontconfig libjpeg bzip2 ];

buildInputs = [ pkgs.gd pkgs.fontconfig pkgs.libjpeg pkgs.bzip2 ];

这是另一个语义相同的例子:

let
  pkgs = import <nixpkgs> {};
  mkDerivation = import ./autotools.nix pkgs;
  gd = pkgs.gd;
  fontconfig = pkgs.fontconfig;
  libjpeg = pkgs.libjpeg;
  bzip2 = pkgs.bzip2;
in mkDerivation {
  name = "graphviz";
  src = ./graphviz-2.38.0.tar.gz;
  buildInputs = [ gd fontconfig libjpeg bzip2 ];
}

在最后一个例子中,gdfontconfig...在let表达式的第一部分被引入范围,然后在buildInputs中使用没有 with pkgs.

希望这能帮助您直观地了解 with pkgs 在做什么。