Giter Club home page Giter Club logo

Comments (4)

rentruewang avatar rentruewang commented on August 27, 2024 1

Oh wow! Thanks for your in depth explanation. Really appreciate it!

from bubbles.

meowgorithm avatar meowgorithm commented on August 27, 2024

Hi! You actually just need to copy the slice to avoid mutating it (since slices are pointers to arrays). There are a few ways to do this. Here's one example:

case "ctrl+q":
	m.inputs = append(m.inputs, textinput.Model{})           // increase the size of the slice by 1
	copy(m.inputs[m.focusIndex+1:], m.inputs[m.focusIndex:]) // shift the tail of the slice by 1
	m.inputs[m.focusIndex] = textinput.NewModel()            // insert a new textinput

from bubbles.

rentruewang avatar rentruewang commented on August 27, 2024

Hi, thanks for the reply! The solution works, that's super helpful!
I'm not sure how I mutated the models by appending some models to the tail of an existing slice, AFAIK, append only copies the structures that's passed in by value, so it shouldn't really modify anything. Do you mind pointing out where mutation happens?

from bubbles.

meowgorithm avatar meowgorithm commented on August 27, 2024

This isn't specific to textinput.Model. Rather, it's how slices work internally in Go. The arguments to append are indeed being passed by value, however slices are just structures that contain pointers to an underlying array. Internally Go represents slices more or less like this:

var underlyingArray [3]string

slice := struct{
    Length:        3,
    ZerothElement: &underlyingArray[0],
}

So if you slice that slice with slice := slice[1:] the representation becomes:

slice := struct{
    Length:        2,
    ZerothElement: &underlyingArray[1],
}

So in the case above, when you append to before you're inserting an element into the same underlying array that after is referencing. This causes after to suddenly be pointing to the wrong position in its underlying array, which happens to be the element that was just appended to before (example). Because of this, you need to use copy to create a new underlying array for after:

slice := []string{"a", "b", "c"}
index := 1

before := slice[:index]

// Copy the tail into a new slice so that it contains a separate underlying array.
after := make([]string, len(slice[index:]))
copy(after, slice[index:])

// Now you can safely append an element to the head and concatenate the two slices.
before = append(before, "NEW")
slice = append(before, after...)
fmt.Printf("%#v\n", slice)

(Playground)

I highly recommend reading Rob Pike's excellent blog post on how append work internally. It’s really good.

from bubbles.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.