瓦拉:传递通用数组会破坏值 [英] Vala: Passing a generic array corrupts values
问题描述
如何将数组传递给泛型函数?以下代码可以编译,但是输出有些损坏:
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);
}
输出:
0
2
4
6
8
113
0
-1521013800
0
0
Output:
0
2
4
6
8
113
0
-1521013800
0
0
我在做什么错了?
推荐答案
您发现了编译器错误.
该数组被视为指针数组,然后当foreach
尝试迭代该指针数组时,事情就出错了.
The array is treated as an array of pointers and then things go wrong when foreach
tries to iterate over that pointer array.
BTW:如果您为32位编译,它会起作用,因为sizeof(gint) == sizeof(gpointer)
在那里.
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.
这可以通过使用Gee.Collection<G>
而不是数组来解决:
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));
}
之所以可行,是因为Gee.Collection<G>
具有其自己的迭代器实现,在这种情况下,这种实现似乎更安全.这也不是一个完美的解决方案,某些Gee类型的值类型参数存在问题,因为他们希望该类型可以为空.
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.
Vala中的泛型总是有些棘手,您不应该将值类型传递给泛型.
Generics in Vala are always a bit tricky, you should not be passing value types into generics.
如果您使用int?
(可空int,它是一种引用类型),它将按预期工作:
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.
代码仍然有点问题,因为您正在将元素强制转换为int
(或者在我的版本中为int?
),但是我想您知道这不是一个好主意,因为这只是一些测试代码,对吧?
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?
这篇关于瓦拉:传递通用数组会破坏值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!