gpt4 book ai didi

d - 你如何在 D 中使用范围?

转载 作者:行者123 更新时间:2023-12-04 10:19:59 26 4
gpt4 key购买 nike

每当我尝试在 D 中使用范围时,我都会失败。

在 D 中使用范围的正确方法是什么? (有关我的困惑,请参阅内嵌评论。)

void print(R)(/* ref? auto ref? neither? */ R r)
{
foreach (x; r)
{
writeln(x);
}

// Million $$$ question:
//
// Will I get back the same things as last time?
// Do I have to check for this every time?

foreach (x; r)
{
writeln(x);
}
}

void test2(alias F, R)(/* ref/auto ref? */ R items)
{
// Will it consume items?
// _Should_ it consume items?
// Will the caller be affected? How do I know?
// Am I supposed to?
F(items);
}

最佳答案

您可能应该阅读 this tutorial on ranges如果你还没有。

何时消耗范围取决于其类型。如果它是输入范围而不是前向范围(例如,如果它是某种类型的输入流 - std.stdio.byLine 就是这样的一个例子),那么以任何形状或形式对其进行迭代都会消耗它。

//Will consume
auto result = find(inRange, needle);

//Will consume
foreach(e; inRange) {}

如果它是一个前向范围并且它是一个引用类型,那么无论何时迭代它都会消耗它,但是你可以调用 save获取它的副本,并且消费副本不会消费原件(消费原件也不会消费副本)。
//Will consume
auto result = find(refRange, needle);

//Will consume
foreach(e; refRange) {}

//Won't consume
auto result = find(refRange.save, needle);

//Won't consume
foreach(e; refRange.save) {}

事情变得更有趣的是作为值类型(或数组)的前向范围。对于 save,它们的作用与任何前向范围相同,但它们的不同之处在于简单地将它们传递给函数或在 foreach 中使用它们隐含 save他们。
//Won't consume
auto result = find(valRange, needle);

//Won't consume
foreach(e; valRange) {}

//Won't consume
auto result = find(valRange.save, needle);

//Won't consume
foreach(e; valRange.save) {}

因此,如果您处理的输入范围不是前向范围,则无论如何都会消耗它。如果您正在处理远期范围,则需要调用 save如果你想保证它不被消耗 - 否则它是否被消耗取决于它的类型。

关于 ref , 如果你声明一个基于范围的函数来接受它的参数 ref ,那么它就不会被复制,所以传入的范围是否是引用类型并不重要,但这确实意味着你不能传递一个右值,这真的很烦人,所以你可能应该不使用 ref在范围参数上,除非您确实需要它总是改变原始(例如 std.range.popFrontN 需要 ref 因为它显式改变原始而不是潜在地对副本进行操作)。

至于使用前向范围调用基于范围的函数,值类型范围最有可能正常工作,因为经常使用值类型范围编写和测试代码,而并不总是使用引用类型进行正确测试。不幸的是,这包括 Phobos 的函数(尽管这将被修复;它只是尚未在所有情况下都经过适当的测试 - 如果您遇到 Phobos 函数在引用类型前向范围内无法正常工作的任何情况, please report it)。因此,引用类型前向范围并不总是像他们应该的那样工作。

关于d - 你如何在 D 中使用范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11190204/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com