[Vala] Puzzled about Gee HashMap and iterating over it with foreach
- From: Paul Jakma <paul jakma org>
- To: vala-list gnome org
- Subject: [Vala] Puzzled about Gee HashMap and iterating over it with foreach
- Date: Tue, 22 Nov 2011 11:37:07 +0000 (GMT)
The below test case has me slightly baffled. Probably I'm just being
extraordinarily dense, and if someone someone enlighten me as to why
'foreach (var f in hashmap)' seems to get V typed f (rather than
Entry<K,V>), and a faulty iterator at that, I'd be very grateful. (the toy
hash function is just for testing).
Also, the Vala tutorial says "For strings and integers the hash and equal
functions are detected automatically". However I found this isn't the
case, at least if you try to use an integer as the key. It seems to treat
integers as (int *), and a Glib int hash func that expects a (ginteger *)
and then obviously a crash when it tries to dereference it. Hence why I
had to supply hash data and key funcs. Can give more details if that isn't
a known problem.
public class Foo : Object {
public int id { get; construct; }
public Foo (int id) {
Object (id : id);
}
}
public static int main (string[] args) {
HashFunc keyfunc = (a) => { return ((uint)a & 0xffff); };
EqualFunc eqfunc = (as1, as2) => { return (as1 == as2); };
var foos = new Gee.HashMap<int, Foo> (keyfunc, eqfunc);
for (int i = 1; i < 4; i++) {
var f = new Foo (i);
stdout.printf ("set %p:%d\n", f, f.id);
foos.set (i, f);
}
stdout.printf ("foos %p, size %d\n", foos, foos.size);
stdout.printf ("foos has: \n");
stdout.printf ("(using foos.values)\n");
foreach (Foo f in foos.values) {
stdout.printf ("%p:%d\n", f, (f != null) ? f.id : 0);
}
// According to the Gee 0.7 documentation, and my local 0.6.1-3.fc16
// VAPI, and the Vala tutorial, iterating with foreach over the bare
// object should use the method from the iterable interface. For 0.6.1
// the AbstractMap VAPI declares it as:
//
// Gee.Iterable<Gee.Map.Entry<K,V>>
//
// and so the returned type for should be Gee.Map.Entry<int,Foo>.
//
// However valac 0.14.0 gives the following error trying to compile this:
//
// hashset-test.vala:31.3-31.44: error: Assignment: Cannot convert from `Foo' to `Gee.Map.Entry<int,Foo>'
// foreach (Gee.Map.Entry<int,Foo> e in foos) {
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//stdout.printf ("(iterate over foos)\n");
//foreach (Gee.Map.Entry<int,Foo> e in foos) {
// Foo f = e.value;
// stdout.printf ("%d: %p:%d\n", e.key, f, (f != null) ? f.id : 0);
//}
// Given the VAPI definition, this shouldn't compile, and it shouldn't
// work. However, given the error produced by the above, then this should
// compile - and it does, without any warning.
// However it doesn't work, as it prints out:
//
// set 0x1a78230:1
// set 0x1a78290:2
// set 0x1a782f0:3
// foos 0x1a7c820, size 3
// foos has:
// (using foos.values)
// 0x1a78230:1
// 0x1a78290:2
// 0x1a782f0:3
// (iterate over foos, wrong way)
// (nil)
// 0x1a78230
// 0x1a78290
//
// -----
// Note the 'nil' and the missing entry.
stdout.printf ("(iterate over foos, wrong way)\n");
foreach (Foo f in foos) {
stdout.printf ("%p\n", f);
}
return 0;
}
--
Paul Jakma paul jakma org twitter: @pjakma PGP: 64A2FF6A
Fortune:
Last yeer I kudn't spel Engineer. Now I are won.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]