D minElement模板容器是如何工作的?

D minElement模板容器是如何工作的?,d,D,在下面的功能中,如果我将a更改为kv: void main() { import std.algorithm.searching : minElement; import std.stdio : writeln; import std.array: byPair; long[string] aa = [ "foo": 5, "bar": 10, "baz": 2000 ]; writeln(aa.b

在下面的功能中,如果我将
a
更改为
kv

void main()
{
    import std.algorithm.searching : minElement;
    import std.stdio : writeln;
    import std.array: byPair;

    long[string] aa = [
        "foo": 5,
        "bar": 10,
        "baz": 2000
    ];
    writeln(aa.byPair().minElement!"a.value"().value); 
}
编译器抛出以下错误消息:

/dlang/dmd/linux/bin64/./../src/phobos/std/functional.d-mixin-215(215):错误:未定义标识符 /dlang/dmd/linux/bin64/./../src/phobos/std/algorithm/search.d(1351):错误:模板实例std.functional.binaryFun!(“千伏值”,“a”,“b”)。二元乐趣!(Tuple!(字符串,“key”,long,“value”),Tuple!(字符串,“key”,long,“value”))实例化错误 /dlang/dmd/linux/bin64/./../src/phobos/std/algorithm/search.d(1314):从这里实例化:极值!(uu lambda2,“kv.value”,MapResult!(u lambda2,Result),Tuple!(字符串,“key”,长,“value”)) /dlang/dmd/linux/bin64/./../src/phobos/std/algorithm/search.d(1398):从这里实例化:极值!((a)=>a,“千伏值”,映射结果!((λ,结果)) /dlang/dmd/linux/bin64/./../src/phobos/std/algorithm/search.d(3550):从这里实例化:极值!(“千伏值”,映射结果!(_lambda2,结果)) onlineapp.d(12):从这里实例化:minElement!(“千伏值”,映射结果!(_lambda2,结果))


但是只使用
参数“a.value”
就可以很好地编译。这是什么意思?

字符串参数作为函数在
std
文档中随处可见,但它们的工作时间和工作方式没有很好的文档记录。正如您所注意到的,
std
采用函数别名参数的模板可以接收字符串而不是实际函数

然后,使用or将该字符串转换为“实”函数,or使用
mixin
或其他魔法。它们将参数命名为
a
b
,您可以使用这些参数


正如Adam D.Ruppe所指出的,您还可以传递“正常”函数/委托,如
minElement!(a=>a.value)(
minElement!((a){return a.value;})
,当然参数名称由您决定。

字符串参数作为函数在
std
文档中随处可见,但它们的工作时间和工作方式没有很好的文档记录。正如您所注意到的,
std
采用函数别名参数的模板可以接收字符串而不是实际函数

然后,使用or将该字符串转换为“实”函数,or使用
mixin
或其他魔法。它们将参数命名为
a
b
,您可以使用这些参数

正如Adam D.Ruppe所指出的,您还可以传递“正常”函数/委托,如
minElement!(a=>a.value)(
minElement!((a){return a.value;})
,当然参数名称由您决定。

用于将传递的字符串转换为函数。然而,要做到这一点,它使用字符串混合。缺点是生成的函数无法访问创建字符串的上下文,因此无法访问其中的变量

正如
unaryFun
的文档所述,字符串中的参数名必须是
a
。这解释了
kv
故障的原因

当然,正如Adam D.Ruppe所说,您应该改为使用更新的lambda语法
kv=>kv.value
——这允许您为我们提供所需的任何参数名称,并允许访问上下文,允许您执行
minElement!(kv=>kv.value+aa[“foo”])
,这在字符串函数中是不可能的

最后,正如您所注意到的,不使用字符串函数的最佳原因之一是错误消息。由于从字符串到函数的转换发生在模板堆栈的深处,因此当实际错误出现在您自己的代码中时,您会得到一个不相关位置的列表,而lambda会在一条易于查找的错误消息中准确地显示错误。

用于将传递的字符串转换为函数。然而,要做到这一点,它使用字符串混合。缺点是生成的函数无法访问创建字符串的上下文,因此无法访问其中的变量

正如
unaryFun
的文档所述,字符串中的参数名必须是
a
。这解释了
kv
故障的原因

当然,正如Adam D.Ruppe所说,您应该改为使用更新的lambda语法
kv=>kv.value
——这允许您为我们提供所需的任何参数名称,并允许访问上下文,允许您执行
minElement!(kv=>kv.value+aa[“foo”])
,这在字符串函数中是不可能的

最后,正如您所注意到的,不使用字符串函数的最佳原因之一是错误消息。由于从字符串到函数的转换发生在模板堆栈的深处,因此当实际错误出现在您自己的代码中时,您会得到一个不相关位置的列表,而lambda会在一条易于查找的错误消息中准确地显示错误。

而不是引号
“a.whatever”
您可以在新的D版本中使用
a=>a.whatever
而不带引号(比3年前更新)。“东西现在有点过时了,不太可靠)而不是引号
“a.whatever”
你可以在新的D版本中使用
a=>a.whatever
,现在不用引号(比3年更新)。“这件事现在有点过时了,不太可靠)