首页 > 解决方案 > minElement 模板容器如何工作?

问题描述

在下面的函数中,如果我更改akv

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):错误:未定义标识符 kv /dlang/dmd/linux/bin64/../。 ./src/phobos/std/algorithm/searching.d(1351): 错误:模板实例 std.functional.binaryFun!("kv.value", "a", "b").binaryFun!(Tuple!(string , "key", long, "value"), Tuple!(string, "key", long, "value")) 实例化 /dlang/dmd/linux/bin64/../../src/phobos/std 时出错/algorithm/searching.d(1314): 从这里实例化: extremum!(__lambda2, "kv.value", MapResult!(__lambda2, Result), Tuple!(string, "key", long, "value")) / dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/searching.d(1398): 从这里实例化: extremum!((a) => a, "kv.value", MapResult !(__lambda2,结果)) /dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/searching.d(3550): 从这里实例化: extremum!("kv.value", MapResult!(__lambda2 , Result)) onlineapp.d(12): 从这里实例化: minElement!("kv.value", MapResult!(__lambda2, Result))

"a.value"但是只需要参数就可以很好地编译。这是什么a意思?

标签: d

解决方案


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

正如unaryFun的文档所述,字符串中的参数名称必须是a. 这解释了为什么kv失败。

当然,正如 Adam D. Ruppe 所说,您应该改用较新的 lambda 语法kv => kv.value——这允许您使用您想要的任何参数名称,并允许访问上下文,让您执行诸如 之类的事情minElement!(kv => kv.value + aa["foo"]),这对于字符串来说是不可能的功能。

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


推荐阅读