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中将创建两个结构:Foo
和FooClass
。前者是人们在 API 中最常使用的,代表 Foo
的一个实例,而后者用于保存 Foo
class 本身的信息;虚函数指针是个大问题。
因此,使用上面的代码,生成的代码将包含 Test
和 TestClass
用于外部 class,以及 TestTestClass
和 TestTestClassClass
用于内部 class。一旦取消注释其余代码,它将尝试生成 TestClass
和 TestClassClass
,前者将与外部 class 的 *Class
结构冲突存在。
您可以更轻松地重现问题:
public class Test : GLib.Object { }
public class TestClass : GLib.Object { }
基本上,不要调用 class *Class
。
下面的例子,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中将创建两个结构:Foo
和FooClass
。前者是人们在 API 中最常使用的,代表 Foo
的一个实例,而后者用于保存 Foo
class 本身的信息;虚函数指针是个大问题。
因此,使用上面的代码,生成的代码将包含 Test
和 TestClass
用于外部 class,以及 TestTestClass
和 TestTestClassClass
用于内部 class。一旦取消注释其余代码,它将尝试生成 TestClass
和 TestClassClass
,前者将与外部 class 的 *Class
结构冲突存在。
您可以更轻松地重现问题:
public class Test : GLib.Object { }
public class TestClass : GLib.Object { }
基本上,不要调用 class *Class
。