Pointers 将nil赋值给指针

Pointers 将nil赋值给指针,pointers,go,Pointers,Go,我正在尝试对列表实现delete()方法(无HEAD ref) 我发现我可以将参数修改为结构 func (l *LinkedList) Delete(n *Node) { if n.next == nil { n = nil } else { current := &n *n = *n.next *current = nil } } “else”部分工作正常,但删除最后一个节点不会修改列表 试用

我正在尝试对列表实现delete()方法(无HEAD ref)

我发现我可以将参数修改为结构

func (l *LinkedList) Delete(n *Node) {
    if n.next == nil {
        n = nil
    } else {
        current := &n
        *n = *n.next
        *current = nil
    }

}
“else”部分工作正常,但删除最后一个节点不会修改列表

试用

*n = nil
但是我有编译错误

无法将nil用作分配中的类型节点

在这个操场上完成代码:


你只是做错了。我的意思是从单链表中删除经典元素。正确的方式:

func (l *LinkedList) Delete(n *Node) {
    // if we want to delete the head element - just move the head pointer
    if l.head == n {
        l.head = n.next
        return
    }
    // otherwise find previous element to the one we are deleting
    current := l.head
    for current != nil && current.next != n {
        current = current.next
    }
    // and move that previous element next pointer to the next element
    if current != nil {
        current.next = n.next
    }
}

那么,你的例子有什么错?在Delete函数中,您将收到指向某个节点的指针。这个指针是函数的局部指针,就像局部变量一样。将nil赋值给函数中的局部变量并不重要。外面-没有人会看到这样的任务。您要做的是更改上一个列表项的下一个指针。这样,项目将不再在列表中。GC将删除实际分配的内存

更新:

由于go指针是“真正的”指针,因此可以通过使用额外的间接级别(如Linus在其著名的(以及前面的-请参阅“最喜欢的黑客”问题)实现,而无需针对头部移除的特殊情况:


IMO两个级别的InDection比删除head元素的简单特例更难理解,但Linus并不像我这样是一个普通的开发人员:)

不确定这是否相关,但您看过内置列表了吗?是的,这更像是如何实现特定的删除案例。感谢您的回答是的,使用head很简单,原始问题的一部分是,如果您只有要删除的节点引用(无head)
void delete\u node(node*node){node->Data=node->Next->Data;node*temp=node->Next->Next;delete(node->Next);node->Next=temp;}
基本上,我正试图在围棋中这样做,以了解指针是如何工作的。[link]@MarianoDM你不能用没有头的单链表。您编写的C代码仅适用于删除非最后一个元素的情况。@kluig如果您要删除头,我认为这不起作用node@Kluyg那么,按照Linus在golang中的建议,是否有必要实施这一点@SasanRose当然可以,go有真正的指针,所以现在开始:IMO的两个间接层次比head元素的简单特例更难理解,但Linus认为不是这样:)
func (l *LinkedList) Delete(n *Node) {
    // initialize indirect with the address of a head pointer
    indirect := &(l.head)
    // until indirect has address of a pointer to the node we're deleting
    for *indirect != n {
        // check that it's not the end of the list
        if (*indirect).next == nil {
            // the node we're tryign to delete is not in the list
            return
        }
        // set indirect to the address of the next pointer
        indirect = &(*indirect).next
    }
    // indirect has address of a pointer we need to modify to delete the node
    *indirect = n.next
}