如何将数组传递给泛型函数?以下代码编译,但输出有点损坏:
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
我做错了什么?
答案 0 :(得分:2)
您发现了编译器错误。
数组被视为一个指针数组,当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类型的值类型参数存在问题,因为它们期望类型可以为空。
Vala中的泛型总是有点棘手,你不应该将值类型传递给泛型。
如果您使用int?
(可为空的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);
}
Nullable类型也不完美,因为它们需要更多内存,并且它们的性能不如值类型,但这就是它的方式。
代码仍然有点问题,因为你将元素转换为int
(或我的版本中的int?
),但我想你知道这不是一个好主意,因为这个只是一些测试代码,对吧?