8

在 Nix 手册的继承属性部分,我们有

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

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

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

import ...(ie )周围的括号有(import ../tools/graphics/graphviz)什么作用?另外,括号里面有inherit (xlibs) libXaw;什么作用?

4

1 回答 1

8

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返回一个函数,然后使用 set 调用该函数{ ... }

括号的必要性可以通过使用与typesOfArgs = one: two: with builtins; "${typeOf one} and ${typeOf two}"返回字符串的函数的参数相同的值来证明。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

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

于 2016-12-20T17:48:47.287 回答