Class 常量问题:如何遍历D中的对象链表?

Class 常量问题:如何遍历D中的对象链表?,class,object,linked-list,d,Class,Object,Linked List,D,如果我有一门课,比如: class Node { string id; const Node next; } 例如,如何查找链接列表中最后一个节点的id string lastID(const Node node) { ??? } 我假设您的问题是您需要循环,但无法重置变量,因为它是常量?如果您希望有一个引用常量对象但自身可重新分配的对象(即它的尾部常量),则使用std.typecons.Rebindable。在这种情况下,这将为您提供: string lastID(

如果我有一门课,比如:

class Node
{
    string id;
    const Node next;
}
例如,如何查找链接列表中最后一个
节点的
id

string lastID(const Node node)
{
    ???
}

我假设您的问题是您需要循环,但无法重置变量,因为它是常量?如果您希望有一个引用常量对象但自身可重新分配的对象(即它的尾部常量),则使用
std.typecons.Rebindable
。在这种情况下,这将为您提供:

string lastID(const Node node)
{
    import std.typecons;
    Rebindable!(const Node) curr = node;

    while(curr.next)
        curr = curr.next;

    return curr.id;
}

我必须说,我觉得这有点奇怪,尽管你不只是问如何对一个引用本身不是常量的常量对象进行引用,因为这就是我所能看到的,你在这里真正要问的,考虑到循环本身是多么的简单。就目前情况而言,您的问题有点过于笼统,要求他人为您编写代码,而不是提出问题。

我认为您的问题在于需要循环,但无法重置变量,因为它是常量?如果您希望有一个引用常量对象但自身可重新分配的对象(即它的尾部常量),则使用
std.typecons.Rebindable
。在这种情况下,这将为您提供:

string lastID(const Node node)
{
    import std.typecons;
    Rebindable!(const Node) curr = node;

    while(curr.next)
        curr = curr.next;

    return curr.id;
}

我必须说,我觉得这有点奇怪,尽管你不只是问如何对一个引用本身不是常量的常量对象进行引用,因为这就是我所能看到的,你在这里真正要问的,考虑到循环本身是多么的简单。就目前而言,你的问题有点过于笼统,要求别人为你编写代码,而不是提出问题。

你也可以尝试使用递归:

string lastID(const Node node)
{
    if(node.next)
        return lastID(node.next);
    return node.id;
}

请记住,如果列表很长(据我所知,D不支持尾部调用递归优化),可能会导致堆栈溢出。

您也可以选择使用递归:

string lastID(const Node node)
{
    if(node.next)
        return lastID(node.next);
    return node.id;
}

请记住,如果列表很长(据我所知,D不支持尾部调用递归优化),可能会导致堆栈溢出。

是的,这正是问题所在——我不能循环,因为它是常量,我不能中断
const
,因为这是未定义的行为。似乎
Rebindable
就是答案,我完全忘记了这个结构;谢谢。@Mehrdad,舍弃常量不是未定义的。它是舍弃
const
,然后对未定义的进行变异。是的,这正是问题所在——我不能循环,因为它是常量,我不能破坏
const
,因为这是未定义的行为。似乎
Rebindable
就是答案,我完全忘记了这个结构;谢谢。@Mehrdad,舍弃常量不是未定义的。它是舍弃
const
,然后对未定义的进行变异。是的,这正是我不使用递归的原因,没有尾部递归的保证是不实用的。dmd目前优化尾部递归,但不是尾部调用。尾部递归==函数将自身作为最后一个表达式调用。Tail call==函数将调用另一个函数作为最后一个表达式。如您所述,如果没有尾部调用优化,相互递归将消耗堆栈。是的,这正是我没有使用递归的原因,没有尾部递归的保证是不实用的。dmd目前优化尾部递归,但不优化尾部调用。尾部递归==函数将自身作为最后一个表达式调用。Tail call==函数将调用另一个函数作为最后一个表达式。如您所述,如果没有尾部调用优化,相互递归将消耗堆栈。