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

时间:2018-12-16 17:50:07

标签: 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;

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;
  }
}

但是,如果我注释了标记为“当前”的行,并且取消注释了注释的代码,则会出现此错误:

$ 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相同的级别上编译另一个类,但是我不得不“另外”包含另一个主应用程序类中的课程?

1 个答案:

答案 0 :(得分:4)

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

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

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

您可以使用以下命令更轻松地重现该问题:

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

基本上,不要调用类*Class