问题
How can I pass an array to a generic function? The following code does compile, but the output gets somewhat corrupted:
void foo<T> (T[] arr) {
foreach (T element in arr) {
var element2 = (int) element;
stdout.printf (element2.to_string() + "\n");
}
}
void main () {
int[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
foo<int> (array);
}
Output:
0
2
4
6
8
113
0
-1521013800
0
0
What am I doing wrong?
回答1:
You discovered a compiler bug.
The array is treated as an array of pointers and then things go wrong when foreach
tries to iterate over that pointer array.
BTW: It works if you compile for 32-Bit, because sizeof(gint) == sizeof(gpointer)
there.
The compiler should not allow a value typed array to be passed to the generic function.
This can be fixed by using Gee.Collection<G>
instead of an array:
void foo<T> (Gee.Collection<T> coll) {
foreach (T element in coll) {
var element2 = (int) element;
stdout.printf (element2.to_string() + "\n");
}
}
void main () {
int[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
foo<int> (new Gee.ArrayList<int>.wrap (array));
}
This works because Gee.Collection<G>
has it's own iterator implementation which seems to be safer in this case. It's not a perfect solution either, some Gee types have problems with value type parameters, because they expect the type to be nullable.
Generics in Vala are always a bit tricky, you should not be passing value types into generics.
If you use an int?
(nullable int, which is a reference type) it works as expected:
void foo<T> (T[] coll) {
foreach (T element in coll) {
var element2 = (int?) element;
stdout.printf (element2.to_string() + "\n");
}
}
void main () {
int?[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
foo (array);
}
Nullable types aren't perfect either, because they need more memory and they don't perform as good as value types, but that's just the way it is.
The code is still a bit problematic, because you are casting the element to an int
(or int?
in my version), but I think you know that it's not a good idea, since this is only some test code, right?
来源:https://stackoverflow.com/questions/39449884/vala-passing-a-generic-array-corrupts-values