为什么我不能在Vala中的类之外声明类(错误:重新定义结构)?

为什么我不能在Vala中的类之外声明类(错误:重新定义结构)?,vala,Vala,下面的示例,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; pub

下面的示例,
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
的类之外编译一个额外的类-但我必须将另一个类“包括”在主应用程序类中?

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

当您创建一个对象时,我们将其称为
Foo
,在Vala中,在生成的C中,将创建两个结构:
Foo
FooClass
。前者是人们在API中最常用的,表示
Foo
的一个实例,而后者用于保存有关
Foo
类本身的信息;虚拟函数指针是一件大事

因此,使用上述代码,生成的代码将包含外部类的
Test
TestClass
,以及内部类的
TestClass
testclassclass
。一旦您取消注释代码的其余部分,它将尝试生成
TestClass
TestClassClass
,前者将与已经存在的外部类的
*Class
结构冲突

您只需执行以下操作,就可以更轻松地再现该问题:

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

基本上,不要调用类
*class

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

当您创建一个对象时,我们将其称为
Foo
,在Vala中,在生成的C中,将创建两个结构:
Foo
FooClass
。前者是人们在API中最常用的,表示
Foo
的一个实例,而后者用于保存有关
Foo
类本身的信息;虚拟函数指针是一件大事

因此,使用上述代码,生成的代码将包含外部类的
Test
TestClass
,以及内部类的
TestClass
testclassclass
。一旦您取消注释代码的其余部分,它将尝试生成
TestClass
TestClassClass
,前者将与已经存在的外部类的
*Class
结构冲突

您只需执行以下操作,就可以更轻松地再现该问题:

public class Test : GLib.Object { }
public class TestClass : GLib.Object { }
基本上,不要调用类
*class