es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Confundido/a acerca de la asignación de tipo de referencia.

A continuación se muestra una parte de una implementación de una lista enlazada y estoy confundido acerca de la semántica:

class Node<t> {
    var value: T
    var next: Node?
    weak var previous: Node?

init(value: T) {
    self.value = value
}
}

struct LinkedList<t> {
    var head: Node<t>?
    var tail: Node<t>?

init() { }

// lo que hace en realidad este método no es importante, pero crea una lista enlazada a partir de una secuencia
func createChain<s>(of sequence: S) -> (head: Node<t>, tail: Node<t>)? where S: Sequence, S.Element == T {
    var iterator = sequence.makeIterator()
    guard let firstValue = iterator.next() else {
        return nil
    }
    var head: Node<t>
    var tail: Node<t>

    var currentNode = Node(value: firstValue)
    head = currentNode

    while let nextValue = iterator.next() {
        let newNode = Node(value: nextValue)
        currentNode.next = newNode
        newNode.previous = currentNode
        currentNode = newNode // ?
    }

    tail = currentNode
    return (head: head, tail: tail)
}
}

Digamos que quiero crear una lista enlazada usando el código anterior:

let linkedList = LinkedList<int>()
let sequence = [0, 1, 2]
let chain = linkedList.createChain(of: sequence)

En la primera iteración del bucle while, la instantánea sería la siguiente:

while let nextValue = iterator.next() {
    let newNode = Node(value: nextValue) // newNode: previous = nil, next = nil, value = 1
    currentNode.next = newNode // currentNode: previous = nil, next = newNode, value = 0
    newNode.previous = currentNode // newNode: previous = currentNode, next = nil, value = 1
    currentNode = newNode // ?
}

Cuando se ejecuta la última línea, entiendo superficialmente que el nuevo nodo debe reemplazar al nodo actual continuamente para recorrer todos los elementos de la secuencia, pero no estoy seguro de qué está ocurriendo exactamente cuando currentNode establece newNode. No tiene sentido que newNode sobrescriba a currentNode ya que el next de currentNode acaba de ser asignado como newNode y el next de newNode es nil.

Si newNode no está sobrescribiendo a currentNode, ¿cómo es posible que el contenido de newNode no afecte a currentNode en currentNode = newNode?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    En la línea currentNode = newNode, la referencia currentNode simplemente se actualiza para apuntar al recién creado newNode. Esto significa que currentNode ahora apunta a una ubicación de memoria diferente a la que apuntaba anteriormente, y ya no está apuntando a la misma instancia que antes.

    Sin embargo, la instancia de Node a la que currentNode apuntaba anteriormente todavía está en memoria y no ha sido modificada. Cuando se crea newNode, sus propiedades previous y next se establecen automáticamente en nil, por lo que no afectan a la propiedad next de la instancia de currentNode que ya había sido establecida en la línea anterior.

    Por lo tanto, cuando se ejecuta currentNode = newNode, lo único que cambia es la referencia que contiene la variable currentNode: ahora apunta al recién creado newNode, aunque la instancia anterior de Node permanece sin cambios en memoria.

Comments are closed.