• No se han encontrado resultados

O pós-25 de Abril de 1974

In document '''' TEATRO INFANTIL. (página 140-158)

B. En cuanto al llamado texto espectacular se observan también algunos aspectos que definen la especificidad del teatro infantil y

5. O pós-25 de Abril de 1974

If we need to append to a slice we can use the built-inappend()function. This function takes the slice to be appended to and one or more individual items to append. If we want to append a slice to a slice we must use the... (ellipsis) operator to tell Go to pass the slice to be added as individual values. The values to append must be of the same type as the slice’s value type. In the case of a string we can append its individual bytes to a byte slice by using the ellipsis syntax.

s := []string{"A", "B", "C", "D", "E", "F", "G"}

t := []string{"K", "L", "M", "N"}

u := []string{"m", "n", "o", "p", "q", "r"}

s = append(s, "h", "i", "j") // Append individual values s = append(s, t...) // Append all of a slice's values s = append(s, u[2:5]...) // Append a subslice

b := []byte{'U', 'V'}

letters := "wxy"

b = append(b, letters...) // Append a string's bytes to a byte slice fmt.Printf("%v\n%s\n", s, b)

[A B C D E F G h i j K L M N o p q]

UVwxy

The built-inappend()function takes a slice and one or more values and returns a (possibly new) slice which has the original slice’s contents, plus the given value or values as its last item or items. If the original slice’s capacity is sufficient for the new items (i.e., its length plus the number of new items is within its

capac-★One compiler does this as follows. Whenever a method is created that operates on a value, say it is calledMethod(), a wrapper method of the same name and signature is created that has a pointer receiver—in effect,func (value*Type) Method() { return (*value).Method() }.

ptg7913109 ity),append()puts the new value or values in the empty position or positions at

the end and returns the original slice with its length increased by the number of items added. If the original slice doesn’t have sufficent capacity, theappend() function creates a new slice under the hood and copies the original slice’s items into it, plus the new value or values at the end, and returns the new slice—hence the need to assignappend()’s return value to the original slice variable.

It sometimes occurs that we want to insert items at the front or in the middle of a slice, not just at the end. Here are some examples that use a custom InsertStringSliceCopy()function that takes a slice to insert into, a slice to insert, and the index position where the insertion should be made.

s := []string{"M", "N", "O", "P", "Q", "R"}

x := InsertStringSliceCopy(s, []string{"a", "b", "c"}, 0) // At the front y := InsertStringSliceCopy(s, []string{"x", "y"}, 3) // In the middle z := InsertStringSliceCopy(s, []string{"z"}, len(s)) // At the end fmt.Printf("%v\n%v\n%v\n%v\n", s, x, y, z)

[M N O P Q R]

[a b c M N O P Q R]

[M N O x y P Q R]

[M N O P Q R z]

The customInsertStringSliceCopy()function creates a new slice (which is why slicesis unchanged at the end of the snippet), making use of the built-incopy() function to copy the first slice it is given and to insert the second slice.

func InsertStringSliceCopy(slice, insertion []string, index int) []string { result := make([]string, len(slice)+len(insertion))

at := copy(result, slice[:index]) at += copy(result[at:], insertion)

copy(result[at:], slice[index:]) return result

}

The built-incopy()function takes two slices (which could be portions of the same slice—even overlapping ones) that contain items of the same type. The function copies the items into the first (destination) slice from the second (source) slice and returns the number of items copied. If the source slice is empty, thecopy() function will safely do nothing. If the destination slice’s length is insufficient to accommodate the source slice’s items, the items that don’t fit are silently ignored. If the destination slice’s capacity is greater than its length, we can increase its length to its capacity with the statementslice = slice[:cap(slice)], before doing the copy.

ptg7913109 The slices passed to the built-incopy()function must be of the same

type—ex-cept that if the first (destination) slice is a[]bytethe second (source) argument may be a[]byteor astring. If the source is a string, its bytes are copied into the first argument. (An example of this use is shown in Chapter 6,➤ 268.)

In the custom InsertStringSliceCopy() function, we begin by creating a new slice (result) that is large enough to hold the items from the two slices passed in. Then we copy a subslice of the first slice (slice[:index]) into theresultslice.

Next we copy the insertion slice into theresult slice starting at the position in the result slice we have reached (at). Then we copy the rest of the first slice (slice[index:]) into theresultslice at the next position we have reached (at). For this last copy we ignore thecopy()function’s return value since we don’t need it.

And finally, we return theresultslice.

If theindex position is0, theslice[:index]in the first copy statement will be slice[:0] (i.e., an empty slice), so no copying is done. Similarly, if theindexis greater than or equal to the length of theslicetheslice[index:]in the last copy statement will effectively beslice[len(slice):](i.e., an empty slice), so again, no copying is done.

Here is a function that has almost the same behavior as the InsertStringSlice-Copy()function, but with much shorter and simpler code. The difference is that theInsertStringSlice()function changes the original slice (and possibly the in-serted slice), whereas theInsertStringSliceCopy()function does not.

func InsertStringSlice(slice, insertion []string, index int) []string { return append(slice[:index], append(insertion, slice[index:]...)...) }

TheInsertStringSlice()function appends the end of the originalslicefrom the indexposition onto the end of theinsertionslice, and then appends the resultant slice onto the end of the originalsliceat theindexposition. The returned slice is the originalslicewith the insertion applied. (Recall thatappend()takes a slice and one or more values, so we must use the ellipsis syntax to transform a slice into its individual values—and in this example, we must do so twice.)

Items can be removed from the beginning and end of slices using Go’s standard slice syntax, but removing from the middle can require a little care. We will start by seeing how to remove from the start, end, and middle of a slice, working on the slice in-place. Then we will see how to take a copy of a slice with items removed that leaves the original slice unchanged.

s := []string{"A", "B", "C", "D", "E", "F", "G"}

s = s[2:] // Remove s[:2] from the front fmt.Println(s)

[C D E F G]

ptg7913109 Removing items from the start of a slice is easily achieved by reslicing.

s := []string{"A", "B", "C", "D", "E", "F", "G"}

s = s[:4] // Remove s[4:] from the end fmt.Println(s)

[A B C D]

Removing items from the end of a slice is achieved by reslicing, just the same as for removing at the start.

s := []string{"A", "B", "C", "D", "E", "F", "G"}

s = append(s[:1], s[5:]...) // Remove s[1:5] from the middle fmt.Println(s)

[A F G]

Retrieving items from the middle of a slice is easy—for example, to get the three middle items of slices, we would use the expressions[2:5]. But to remove items from the middle of a slice is slightly tricky. Here we have done the removal using theappend()function to append the subslice of slicesthat follows what we want to delete, to the subslice of slices that precedes what we want to delete, and assigning the resultant slice back tos.

Clearly, using append() and assigning back to the original slice to remove items, changes the original slice. Here are some examples that use a custom RemoveStringSliceCopy()function that returns a copy of the slice it is given, but with the items from the start and end index positions removed.

s := []string{"A", "B", "C", "D", "E", "F", "G"}

x := RemoveStringSliceCopy(s, 0, 2) // Remove s[:2] from the front y := RemoveStringSliceCopy(s, 1, 5) // Remove s[1:5] from the middle z := RemoveStringSliceCopy(s, 4, len(s)) // Remove s[4:] from the end fmt.Printf("%v\n%v\n%v\n%v\n", s, x, y, z)

[A B C D E F G]

[C D E F G]

[A F G]

[A B C D]

Since theRemoveStringSliceCopy()function copies the items, the original slice is left intact.

func RemoveStringSliceCopy(slice []string, start, end int) []string { result := make([]string, len(slice)-(end-start))

at := copy(result, slice[:start])

ptg7913109 copy(result[at:], slice[end:])

return result }

In the customRemoveStringSliceCopy()function, we begin by creating a new slice (result) that is large enough to hold the items it will contain. Then we copy a subslice of the slice up to thestartposition (slice[:start]) into theresultslice.

Next we copy the slice from theendposition (slice[end:]) into theresultslice at the position we have reached (at). And finally, we return theresultslice.

It is also possible to create a simplerRemoveStringSlice()function that works on the slice it is given rather than making a copy.

func RemoveStringSlice(slice []string, start, end int) []string { return append(slice[:start], slice[end:]...)

}

This is a generalization of the remove from the middle example that used the built-inappend()function shown earlier. The returned slice is the originalslice with the items from the start position up to (but excluding) theend position removed.

In document '''' TEATRO INFANTIL. (página 140-158)