generics - Vala:传递通用数组会破坏值

标签 generics vala

如何将数组传递给通用函数?以下代码确实可以编译,但输出有些损坏:

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/

相关文章:

swift - 从 SHA256.hash(data :)?

java - 如何为参数列表和/或返回类型中的 "any map entry"值创建通用方法签名?

Java 8 - Wildcard extends with BiPredicate 不工作

vala - 使用 Vala 的默认应用程序打开文件?

c# - C#'s equivalent of Java' s 通配符

java - 带有类型参数的 Guice 模块

gtk3 - 如何在 anjuta 项目中包含资源文件

vala - 没有实例方法或闭包的目标无法创建委托(delegate)是什么意思

Gtk+ 和 Vala : Inheriting gtk. TreeModel

linux - 销毁类实例不会杀死它在 vala 中拥有的实例