瓦拉:传递通用数组会破坏值 [英] Vala: Passing a generic array corrupts values

查看:52
本文介绍了瓦拉:传递通用数组会破坏值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将数组传递给泛型函数?以下代码可以编译,但是输出有些损坏:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆