Why cannot I declare class outside of class in Vala (error: redefinition of struct)?

Why cannot I declare class outside of class in Vala (error: redefinition of struct)?

下面的例子,test4.vala,编译并运行:

//// compile with: valac test4.vala

//~ public class TestClass : GLib.Object { // error: redefinition of ‘struct _TestClass’
  //~ public int x = 0;
  //~ public int y = 0;
  //~ public int z = 0;
//~ }

public Test App;

public class Test : GLib.Object {

  public class TestClass : GLib.Object {  //current
    public int x = 0;                     //current
    public int y = 0;                     //current
    public int z = 0;                     //current
  }                                       //current

  public TestClass mytc;
  public void SetVars() {
    mytc = new TestClass();
    stdout.printf("SetVars called, %p\n", mytc);
  }

  public Test(string[] args){
    stdout.printf("Test() ctor: ok\n");
    stdout.flush();
  }

  public static int main (string[] args) {
    App = new Test(args);
    App.SetVars();
    stdout.printf("main called\n");
    return 0;
  }
}

但是,如果我对标记为 "current" 的行进行注释并取消对注释代码的注释,则会出现此错误:

$ valac test4.vala && ./test4 
/tmp/test4.vala.c:64:8: error: redefinition of ‘struct _TestClass’
 struct _TestClass {
        ^~~~~~~~~~
/tmp/test4.vala.c:20:16: note: originally defined here
 typedef struct _TestClass TestClass;
                ^~~~~~~~~~
error: cc exited with status 256
Compilation failed: 1 error(s), 0 warning(s)

我仍在尝试理解 Vala,但这有点让我感到困惑 - 为什么我不能在携带 main 的那个之外编译一个额外的 class 与它处于同一水平 - 但我必须而不是 "include" 这个另一个 class 在主应用 class?

这与 GObject 的工作方式及其命名约定有关。 GObject手册有more details,所以我不打算在这里深入…

当你创建一个对象时,我们称它为Foo,在Vala中,在生成的C中将创建两个结构:FooFooClass。前者是人们在 API 中最常使用的,代表 Foo 的一个实例,而后者用于保存 Foo class 本身的信息;虚函数指针是个大问题。

因此,使用上面的代码,生成的代码将包含 TestTestClass 用于外部 class,以及 TestTestClassTestTestClassClass 用于内部 class。一旦取消注释其余代码,它将尝试生成 TestClassTestClassClass,前者将与外部 class 的 *Class 结构冲突存在。

您可以更轻松地重现问题:

public class Test : GLib.Object { }
public class TestClass : GLib.Object { }

基本上,不要调用 class *Class