Updating golang array while iterating it - arrays

When iterating an array with range, if the array is updated the updated positions do not make it into the future loop runs. The following prints "1 2" instead of "1 0"
package main
import (
"fmt"
)
func main() {
var A = &[2]int{1, 2}
for i, v := range A {
if i == 0 {
A[1] = 0
}
fmt.Print(v, " ")
}
fmt.Println()
var B = [2]int{1, 2}
for i, v := range B {
if i == 0 {
B[1] = 0
}
fmt.Print(v, " ")
}
}
https://play.golang.org/p/0zZY6vjxwut
It looks like the array is copied before it's iterated.
What part of the spec describes this behavior?
See "For statements with range clause" at https://golang.org/ref/spec#For_range

TLDR; Whatever you range over, a copy is made of it (this is the general "rule", but there is an exception, see below). Arrays are rare in Go, usually slices are used. Slice values (slice headers) contain a pointer to an underlying array, so copying a slice header is fast, efficient, and it does not copy the slice elements, not like arrays. Ranging over a pointer to array is similar to ranging over a slice in this regard.
Spec: For statements:
The range expression x is evaluated once before beginning the loop, with one exception: if at most one iteration variable is present and len(x) is constant, the range expression is not evaluated.
Arrays are values, they do not contain pointers to data located outside of the array's memory (unlike slices). The Go Blog: Go Slices: usage and internals:
Go's arrays are values. An array variable denotes the entire array; it is not a pointer to the first array element (as would be the case in C). This means that when you assign or pass around an array value you will make a copy of its contents. (To avoid the copy you could pass a pointer to the array, but then that's a pointer to an array, not an array.) One way to think about arrays is as a sort of struct but with indexed rather than named fields: a fixed-size composite value.
Evaluating an array is a copy of the entire array, it is a copy of all the elements. Spec: Variables:
A variable's value is retrieved by referring to the variable in an expression; it is the most recent value assigned to the variable.
In your first example the range expression is just a pointer to the array, so only this pointer is copied (but not the pointed array), so when you do A[1] = 0 (which is a shorthand for (*A)[1] = 0), you modify the original array, and the iteration variable gets elements from the pointed array.
In your second example the range expression is the array, so the array (with all its elements) is copied, and inside it B[1] = 0 still modifies the original array (B is a variable, not the result of the evaluation of the range expression), but v is an element of the copy (v is populated from the copied array in each iteration).
Under the hood
So how is this "copy" realized? The compiler generates code for the for range that copies (assigns) the result of the range expression to a temporary variable (if needed, because it might not always be needed: "if at most one iteration variable is present and len(x) is constant, the range expression is not evaluated").
This code can be inspected in the cmd/compile/internal/gc/range.go file.
See related article: Go Range Loop Internals

The spec says
The range expression x is evaluated once before beginning the loop, with one exception: if at most one iteration variable is present and len(x) is constant, the range expression is not evaluated.
Function calls on the left are evaluated once per iteration. For each iteration, iteration values are produced as follows if the respective iteration variables are present
The thing here is that given your loop takes more than one variable, the range expression is evaluated only once at the beginning of the iteration. Thus the value of the B[1] assigned to the v won't change.
In the case with reference, you see the modified value since the expression evaluates the reference to the B[1], which is not modified and prints the value of that referenced variable, which is actually modified.

Related

Last element of a struct array - C

I'm a bit confused about a thing :
If I have an array of structs: table whith a length of X and I want to access the last element of it: table[X] or table[X-1]. If it's table[X-1], what table[X] contains ?
The indexing of array in C starts with zero, i.e. the first element will be in table[0], the second in table[1], the third in table[2] ... and the last on in table[X-1].
table[X] is outside of the arrays bounds. C does not have bounds checking, so compiler allows accessing it, but this is an undefined behaviour, i.e. you will never know what happens. Reading it can give back memory garbage or can lead to an OS exception like segmentation fault.
The answer is the same for any kind of array. If you have one with the size
X :
int a[5];
struct my_struct ms[10];
...
you specify the amount of elements in that array. Because the 1st element is element 0, the last element is always X - 1.
If you try to access the element a[X] you will get undefined behavior.
Structs work in memory the same way that an integer or some other basic data type would in this instances. Your array would just be separated by sizeof(struct) instead of sizeof(the basic data type).
It'd still start at 0, and end at X - 1. The type of arrays usually just really defined 2 things:
The amount of bytes per index, and how to treat the data.
Picture an array of size 3 with structs that contain 5 bytes of data. Your array would just be set as follows:
-----|-----|-----|????|
s1 |s2 |s3 |????|
Just because it exists, doesn't mean our program knows what it is. the 4th [3] index (????) would be an index out of bounds of our array. It is possible however you could get some meaningful value here, but very unlikely. Most of the time it will either be garbage, or cause an error.
Arrays in C use zero indexing, meaning they start with 0 and end with n-1. Not to be confused with array declarations, where you write the size expressed in number of items. The syntax for accessing an array and declaring one looks similar, which is why this can be confusing for beginners.
Example:
int main (void)
{
int array[5]; // allocate an array with 5 elements
array[0] = 0; // access first element
array[4] = 0; // access last element (index 4)
array[5] = 0; // BAD, accessing the array out of bounds: index 5 gives item number 6
}
And this is why the canonical way to write for loops in C is this:
for(int i=0; i<n; i++)
where n is the size of the array, and the iterator i will have the values from 0 to n-1.

Golang mutex ranging over shared array in goroutines

Say I have the following code:
a := []int{1,2,3}
i := 0
var mu = &sync.Mutex{}
for i < 10 {
go func(a *[]int) {
for _, i := range a {
mu.Lock()
fmt.Println(a[0])
mu.Unlock()
}
}(&a)
i++
}
The array is a shared resource and is being read from in the loop. How do I protect the array in the loop header and do I need to? Also is it necessary to pass the array to the goroutine as a pointer?
First, some Go terminology:
[]int{1, 2, 3} is a slice, not an array. An array would be written as [...]int{1, 2, 3}.
A slice is a triplet of (start, length, capacity) and points to an underlying array (usually heap-allocated, but this is an implementation detail that the language completely hides from you!)
Go's memory model allows any number of readers or (but not and) at most one writer to any given region in memory. The Go memory model (unfortunately) doesn't specifically call out the case of accessing multiple indices into the same slice concurrently, but it appears to be fine to do so (i.e. they are treated as distinct locations in memory, as would be expected).
So if you're just reading from it, it is not necessary to protect it at all.
If you're reading and writing to it, but the goroutines don't read and write to the same places as each other (for example, if goroutine i only reads and writes to position i) then you also don't need synchronization. Moreover, you could either synchronize the entire slice (which means fewer mutexes, but much higher contention) or you could synchronize the individual positions in the slice (which means much lower contention but many more mutexes and locks acquired and released).
But since Go allows functions to capture variables in scope (that is, they are closures) there's really no reason to pass the array as a pointer at all:
Your code would thus be most idiomatically be written as:
a := []int{1,2,3}
for i := 0; i < 10; i++
for i < 10 {
go func() {
for _, i := range a {
fmt.Println(a[0])
}
}()
}
I'm not really sure what the above code is supposed to be for- since it's going to print out a[0] 10 times in various goroutines, which makes it look like it's not even using the slice in a meaningful way.
First you shuold know a := []int{1,2,3} is not an array, it is a slice.
A slice literal is like an array literal without the length.
This is an array literal:
[3]bool{true, true, false}
And this creates the same array as above, then builds a slice that
references it:
[]bool{true, true, false}
Types with empty [], such as []int are actually slices, not arrays. In Go, the size of an array is part of the type, so to actually have an array you would need to have something like [16]int, and the pointer to that would be *[16]int.
Q: is it necessary to pass the array to the goroutine as a pointer?
A: No. From https://golang.org/doc/effective_go.html#slices
If a function takes a slice argument, changes it makes to the elements
of the slice will be visible to the caller, analogous to passing a
pointer to the underlying array.

How slice works in GO?

a = make([]int, 7, 15)
creates implicit array of size 15 and slice(a) creates a shallow copy of implicit array and points to first 7 elements in array.
Consider,
var a []int;
creates a zero length slice that does not point to any implicit array.
a = append(a, 9, 86);
creates new implicit array of length 2 and append values 9 and 86. slice(a) points to that new implicit array, where
len(a) is 2 and cap(a) >= 2
My question:
is this the correct understanding?
As I mentioned "Declare slice or make slice?", the zero value of a slice (nil) acts like a zero-length slice.
So you can append to a []int directly.
You would need to make a slice (make([]int, 0) ) only if you wanted to potentially return an empty slice (instead of nil).
If not, no need to allocate memory before starting appending.
See also "Arrays, slices (and strings): The mechanics of 'append': Nil"
a nil slice is functionally equivalent to a zero-length slice, even though it points to nothing. It has length zero and can be appended to, with allocation.

Number sequences length, element first and last indexes in array

Im beginner in programming. My question is how to count number sequences in input array? For example:
input array = [0,0,1,1,1,1,1,1,0,1,0,1,1,1]
output integer = 3 (count one-sequences)
And how to calculate number sequences first and last indexes in input array? For example:
input array = [0,0,1,1,1,1,1,1,0,1,0,1,1,1]
output array = [3-8,10-10,12-14] (one first and last place in a sequence)
I tried to solve this problem in C with arrays. Thank you!
Your task is a good exercise to familiarize you with the 0-based array indexes used in C, iterating arrays, and adjusting the array indexes to 1-based when the output requires.
Taking the first two together, 0-based arrays in C, and iterating over the elements, you must first determine how many elements are in your array. This is something that gives new C programmers trouble. The reason being is for general arrays (as opposed to null-terminated strings), you must either know the number of elements in the array, or determine the number of elements within the scope where the array was declared.
What does that mean? It means, the only time you can use the sizeof operator to determine the size of an array is inside the same scope (i.e. inside the same block of code {...} where the array is declared. If the array is passed to a function, the parameter passing the array is converted (you may see it referred to as decays) to a pointer. When that occurs, the sizeof operator simply returns the size of a pointer (generally 8-bytes on x86_64 and 4-bytes on x86), not the size of the array.
So now you know the first part of your task. (1) declare the array; and (2) save the size of the array to use in iterating over the elements. The first you can do with int array[] = {0,0,1,1,1,1,1,1,0,1,0,1,1,1}; and the second with sizeof array;
Your next job is to iterate over each element in the array and test whether it is '0' or '1' and respond appropriately. To iterate over each element in the array (as opposed to a string), you will typically use a for loop coupled with an index variable ( 'i' below) that will allow you to access each element of the array. You may have something similar to:
size_t i = 0;
...
for (i = 0; i< sizeof array; i++) {
... /* elements accessed as array[i] */
}
(note: you are free to use int as the type for 'i' as well, but for your choice of type, you generally want to ask can 'i' ever be negative here? If not, a choice of a type that handles only positive number will help the compiler warn if you are misusing the variable later in your code)
To build the complete logic you will need to test for all changes from '0' to '1' you may have to use nested if ... else ... statements. (You may have to check if you are dealing with array[0] specifically as part of your test logic) You have 2 tasks here. (1) determine if the last element was '0' and the current element '1', then update your sequence_count++; and (2) test if the current element is '1', then store the adjusted index in a second array and update the count or index for the second array so you can keep track of where to store the next adjusted index value. I will let you work on the test logic and will help if you get stuck.
Finally, you need only print out your final sequence_count and then iterate over your second array (where you stored the adjusted index values for each time array was '1'.
This will get you started. Edit your question and add your current code when you get stuck and people can help further.

What is the difference between ArrayBuffer and Array

I'm new to scala/java and I have troubles getting the difference between those two.
By reading the scala doc I understood that ArrayBuffer are made to be interactive (append, insert, prepend, etc).
1) What are the fundamental implementation differences?
2) Is there performance variation between those two?
Both Array and ArrayBuffer are mutable, which means that you can modify elements at particular indexes: a(i) = e
ArrayBuffer is resizable, Array isn't. If you append an element to an ArrayBuffer, it gets larger. If you try to append an element to an Array, you get a new array. Therefore to use Arrays efficiently, you must know its size beforehand.
Arrays are implemented on JVM level and are the only non-erased generic type. This means that they are the most efficient way to store sequences of objects – no extra memory overhead, and some operations are implemented as single JVM opcodes.
ArrayBuffer is implemented by having an Array internally, and allocating a new one if needed. Appending is usually fast, unless it hits a limit and resizes the array – but it does it in such a way, that the overall effect is negligible, so don't worry. Prepending is implemented as moving all elements to the right and setting the new one as the 0th element and it's therefore slow. Appending n elements in a loop is efficient (O(n)), prepending them is not (O(n²)).
Arrays are specialized for built-in value types (except Unit), so Array[Int] is going to be much more optimal than ArrayBuffer[Int] – the values won't have to be boxed, therefore using less memory and less indirection. Note that the specialization, as always, works only if the type is monomorphic – Array[T] will be always boxed.
The one other difference is, Array's element created as on when its declared but Array Buffer's elements not created unless you assign values for the first time.
For example. You can write Array1(0)="Stackoverflow" but not ArrayBuffer1(0)="Stackoverflow" for the first time value assignments.
(Array1 = Array variable & ArrayBuffer1 = ArrayBuffer variable)
Because as we know, Array buffers are re-sizable, so elements created when you insert values at the first time and then you can modify/reassign them at the particular element.
Array:
Declaring and assigning values to Int Array.
val favNums= new Array[Int](20)
for(i<-0 to 19){
favNums(i)=i*2
}
favNums.foreach(println)
ArrayBuffer:
Declaring and assigning values to Int ArrayBuffer.
val favNumsArrayBuffer= new ArrayBuffer[Int]
for(j<-0 to 19){
favNumsArrayBuffer.insert(j, (j*2))
//favNumsArrayBuffer++=Array(j*3)
}
favNumsArrayBuffer.foreach(println)
If you include favNumsArrayBuffer(j)=j*2 at the first line in the for loop, It doesn't work. But it works fine if you declare it in 2nd or 3rd line of the loop. Because values assigned already at the first line now you can modify by element index.
This simple one-hour video tutorial explains a lot.
https://youtu.be/DzFt0YkZo8M?t=2005
Use an Array if the length of Array is fixed, and an ArrayBuffer if the length can vary.
Another difference is in term of reference and value equality
Array(1,2) == Array(1,2) // res0: Boolean = false
ArrayBuffer(1, 2) == ArrayBuffer(1,2) // res1: Boolean = true
The reason for the difference is == routes to .equals where Array.equals is implemented using Java's == which compares references
public boolean equals(Object obj) {
return (this == obj);
}
whilst ArrayBuffer.equals compares elements contained by ArrayBuffer using sameElements method
override def equals(o: scala.Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (
o match {
case it: Seq[A] => (it eq this) || (it canEqual this) && sameElements(it)
case _ => false
}
)
Similarly, contains behaves differently
Array(Array(1,2)).contains(Array(1,2)) // res0: Boolean = false
ArrayBuffer(ArrayBuffer(1,2)).contains(ArrayBuffer(1,2)) // res1: Boolean = true

Resources