如何将数组传递给通用函数?以下代码确实可以编译,但输出有些损坏:
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
我做错了什么?
最佳答案
您发现了编译器错误。
该数组被视为指针数组,然后当 foreach
时就会出现问题。尝试迭代该指针数组。
顺便说一句:如果您编译为 32 位,它就可以工作,因为 sizeof(gint) == sizeof(gpointer)
那里。
编译器不应允许将值类型数组传递给泛型函数。
这可以通过使用 Gee.Collection<G>
来修复而不是数组:
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 类型在值类型参数方面存在问题,因为它们期望类型可为 null。
Vala 中的泛型总是有点棘手,您不应该将值类型传递到泛型中。
如果您使用 int?
(可为 null int,这是一个引用类型)它按预期工作:
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);
}
可空类型也不完美,因为它们需要更多内存,而且性能不如值类型,但事实就是如此。
代码仍然有点问题,因为您正在将元素强制转换为 int
(或者在我的版本中为 int?
),但我想您知道这不是一个好主意,因为这只是一些测试代码,对吗?
关于generics - Vala:传递通用数组会破坏值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39449884/