D (The Programming Language)/d2/Slicing

=Lesson 9: Slicing and a Deeper Look into Dynamic Arrays= Slicing in D is one of the language's most powerful and useful aspects. This lesson is really more of a continuation of the last lesson - you will also get a deeper look into how D's arrays work.

What are Slices?
You can take slices of arrays in D with this syntax: The element at  is not included in the slice. Remember that dynamic arrays are just structures with a pointer to the first element and a length value. Taking a slice of a dynamic array simply creates a new one of those pointer structures that points to the elements of that same array.

Three Ways to Do the Same Thing
Notice that the  is automatically replaced with the length of the array being sliced from. The following three lines are equivalent and both create slices of the entirety of an array.

The Property
All dynamic arrays in D have a  property. It is the maximum number of elements that can be appended to that array without having to move the array somewhere else (reallocation).

Maximizing Efficiency by Only Reallocating When Necessary
It is good for efficiency to make sure that appending and concatenation do not cause too many reallocations because it is an expensive procedure to reallocate a dynamic array. The following code may reallocate up to 5 times: Make sure that the array  is big enough at the beginning to allow for efficient non-reallocating array appends and concatenations later if performance is a concern. You can't modify the  property. You are only allowed to either modify the length, or use the  function.

When Passed to Functions
Remember that D's arrays are passed to functions by value. When static arrays are passed, the entire array is copied. When a dynamic array is passed, only that structure with the pointer to the underlying array and the length is copied - the underlying array is not copied. As you can see, there are a few possibilities if you pass a dynamic array to a function that looks like this:
 * First possibility: the array's capacity was large enough to accommodate the resizing, so no reallocation occurred. The original underlying array's first element was modified.
 * Second possibility: the array's capacity was not large enough to accommodate the resizing, but D's memory management was able to extend the memory space without copying the entire array. The original underlying array's first element was modified.
 * Third possibility: the array's capacity was not large enough to accommodate the resizing. D's memory management had to reallocate the underlying array into a completely new space in memory.  The original underlying array's first element was not modified.

What if you want to make sure that the following works?

Simply change the function  so that dynamic arrays are passed by reference:

Appending to Slices
When you take a slice of a dynamic array, and then append to that slice, whether the slice is reallocated depends on where the slice ends. If the slice ends in the middle of the data from the original array, then appending to that slice would cause a reallocation. Lets say you took a slice of a dynamic array, and that slice ends at where the dynamic array ends. What if you appended to the dynamic array so that the slice no longer ends at where the dynamic array's data ends? The  property of a slice does indeed depend on other references to the same data.

Assignment-To-Slices
An Assignment-To-Slice looks like this: You are assigning  to a slice of  You have actually seen Assignment-to-Slices in the last two lessons, even before you learned about slices. Remember this? Remember that  is shorthand for When you assign a  slice to a single   value, that   value is assigned to all the elements within that slice. An Assignment-To-Slice always causes data to be copied. Beware! Whenever you use Assignment-To-Slice, the left and right sides'  values must match! If not, there will be a runtime error! You also must make sure that the left and right slices do not overlap.

Vector Operations
Let's say you wanted to double each and every integer element of an array. Using D's vector operation syntax, you can write any of these: Likewise, if you wanted to perform this operation:    [1, 2, 3, 4] (int[] a)  + [3, 1, 3, 1] (int[] b)  = [4, 3, 6, 5]  You would write this: Just like for Assignment-To-Slice, you have to make sure the left and right sides of vector operations have matching lengths, and that the slices do not overlap. If you fail to follow that rule, the result is undefined (There would be neither a runtime error nor a compile-time error).

Defining Array Properties
You can define your own array properties by writing functions in which the first argument is an array.

Tips

 * Steven Schveighoffer's article "D Slices" is an excellent resource if you want to learn more.