从 Nix 表达式语言中的另一个集合继承属性

Inherit Attributes from Another Set in Nix Expression Language

在 Nix 手册的 Inheriting attributes 部分,我们有

graphviz = (import ../tools/graphics/graphviz) {
  inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
  inherit (xlibs) libXaw;
};

xlibs = {
  libX11 = ...;
  libXaw = ...;
  ...
}

libpng = ...;
libjpg = ...;
...

import ...(即 (import ../tools/graphics/graphviz))两边的括号有什么作用?另外,inherit (xlibs) libXaw;中的括号是做什么用的?

xlibs 与 graphviz 在同一范围内,但 libXaw 不是,因为它在 xlibs 集合内。因此,为了能够将其作为参数传递给 graphviz 函数,您需要显式 inherit (xlibs) libXaw。括号表示的行为是 inherit 关键字所独有的。

(import ../tools/graphics/graphviz) 中的括号只是表示评估顺序的通用约定。 import 是一个接受单个参数 path 的函数。 ../tools/graphics/graphviz 中的文件包含一个接受一组属性作为参数的函数。因此括号表示求值顺序应该是 (1) 在 path 中导入函数,然后 (2) 将属性集 {...} 应用到该函数。


编辑:@danbst 指出,在这种情况下,不需要 import ../tools/graphics/graphviz 中的括号。这样做的原因是评估 import ../tools/graphics/graphviz returns 一个函数,然后用集合 { ... } 调用该函数。

括号的必要性可以通过使用与此函数的参数相同的值来证明 typesOfArgs = one: two: with builtins; "${typeOf one} and ${typeOf two}" 其中 returns 一个字符串。 typesOfArgs (import ../tools/graphics/graphviz) { } 会求值为 "lambda and set" 但如果没有括号,解释器会将 typesOfArgs import ../tools/graphics/graphviz 求值为 "lambda and path" 然后尝试将该字符串作为带有参数 { } 的函数来调用这将导致 error: attempt to call something which is not a function but a string

如果没有方括号,解释器会假设您想使用两个参数 path{ ... } 调用函数 import,这将是一个错误。