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年更新)。“这件事现在有点过时了,不太可靠)