开发者

Associative Array where a class TypeInfo is key in D?

I'd like to be able to create an multidim associative array where one dimension is a class. Like this:

class Node{
    Node[?classType?][string] inputs;
}

so that I later can do

Node[] getInputsOfType(?? aClass){
   if(aClass in this.inputs)
      return this.inputs[aClass];
   else
      return null;
}

// meanwhile in another file...

Node[] effects = someAudioNode.getInputsOfType(AudioEffect);

I'm just lost. Any ideas?

Regarding the last part: Can a class be used as a parameter all by itself like that? (AudioEffect in this example is a class.)

BR

[update/resolution]

Thanks for the answer(s)!

I thought it'd be nice to post the result. Ok, I looked up .classinfo in the source code and found that it returns an instance of TypeInfo_Class, and that there's a .name-property, a string. So this is what I came up with:

#!/usr/bin/env dmd -run
import  std.stdio;
class A{
    int id;
    static int newId;
    A[string][string] list;
    this(){ id = newId++; }
    void add(A a, string name){
        writefln("Adding: [%s][%s]", a.classinfo.name, name);
        list[a.classinfo.name][name] = a;
    }
    T[string] getAllOf(T)(){
        return cast(T[string]) list[T.classinfo.name];
    }
}
class B : A{ }
void main(){
    auto a = new A();
    a.add(new A(), "test");
    a.add(new B(), "bclass");
    a.add(new B(), "bclass2");

    auto myAList = a.getAllOf!(A);
    foreach(key, item; myAList)
        writefln("k: %s, i: %s id: %s",
                key, item.toString(), item.id);

    auto myBList = a.getAllOf!(B);
    foreach(key, item; myBList)
        writefln("k: %s, i: %s id: %s",
                key开发者_运维问答, item.toString(), item.id);
}

It outputs:

Adding: [classtype.A][test]
Adding: [classtype.B][bclass]
Adding: [classtype.B][bclass2]
Trying to get [classtype.A]
k: test, i: classtype.A id: 1
Trying to get [classtype.B]
k: bclass2, i: classtype.B id: 3
k: bclass, i: classtype.B id: 2

So yeah, I suppose it works. Yey! Anyone has ideas for improvement?

Are there any pitfalls here?

  • Can classinfo.name suddenly behave unexpedictly?
  • Is there a »proper» way of getting the class name?

Also, is this the fastest way of doing it? I mean, all class names seems to start with classtype.. Oh well, that's perhaps another SO-thread. Thanks again!

BR


You can use the ClassInfo class (accessible through the .classinfo property) to refer to class types at runtime. However, the ClassInfo class doesn't implement the necessary methods to be used in an associative array (see the D reference page on AAs regarding using classes/structs in AAs). I suppose this is possible if you implement your own wrapper for ClassInfo that can be used as an AA key. This should be fairly simple, as you can expect that a class type will have only one ClassInfo instance, thus you can simply use the ClassInfo's address as the unique hash.


By the way, a simpler and faster way to write

if (key in aa)
    return aa[key];
else
    return null;

is

auto pvalue = key in aa;
return pvalue ? *pvalue : null;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜