Jérôme Richard's answer has the most important part in it: don't worry about this kind of micro-optimization unless/until you have a benchmark showing that it's important.
I'll answer from the Go and C sides in a different way though. The two bits of code have different meanings here. (I'm not really a Java programmer so I'll just refer to Aliasing in Java with Arrays and Reference Types for the Java variant of this point.) Let's also change the code so that we have a mystery function, rather than some known-to-do-nothing-but-print function:
/* C */
extern void f(int);
void test(int *arr) {
int i;
for (i = 0; i < (1 << 20); i++) {
f(arr[0]);
}
}
// Go
func test(arr []int, f func(int)) {
for i := 0; i < (1 << 20); i++ {
f(arr[0])
}
}
Now let's consider a valid call to test. Here's part of the C-language implementation of f:
extern int A[];
void f(int arg) {
/* do something with arg */
A[0]++;
}
The call to test reads:
test(A);
That is, arr in test is A, and f() modifies A[0]. So each call to f() needs to pass a different integer value.
If you modify test to read:
/* C */
extern void f(int);
void test(int *arr) {
int i;
int arg = arr[0];
for (i = 0; i < (1 << 20); i++) {
f(arg);
}
}
then suddenly each call to f passes the original value only from A[0]. So these programs have different meanings.
Go and C have similar aliasing rules. However, Go compilers can often "see further" than C compilers (because the compiler usually gets a better chance to do function inlining, if nothing else) and hence detect whether or not some aliasing may be taking place. It's easier, in a sense, for a Go compiler to grab the arr[0] value once outside the loop, if that's possible, than it is for the C compiler. That's not a function of the language itself: it's a function of the traditional ways that C and Go compilers have been written.
Still, the upshot of all this is that if you intend to pass the same value to your function every trip through the loop, you can write that as code by copying arr[0] to a local variable before running the loop. If you intend to allow arr[0] to be modified each trip through the loop, you can write that by writing the variant without a local variable—but it might also be wise to put in a comment, noting that the called function is intended to be able to modify the array element.
Write the code so that the reader can understand the intent first. Then, if and when it proves to be a bottleneck, write the code in some more-obscure-but-faster form, if that's possible and appropriate.