前段时间用vala开发了一个很小的程序,体验了一把vala的使用,网上关于vala的文章比较少,所以写一篇博客,如果你有相同的使用经验可以交流下.
根据百度百科的解释,vala是一种新的、为GNOME开发者提供的具有现代化编程语言功能的一种编程语言。Vala是一种和C#极度类似的语言。
众所周知,C是一门古老而落后的语言,虽然由于历史原因,大量的操作系统底层仍然在使用C(毕竟最早写底层的那批人早就退休甚至不在人世了,谁又愿意没事找事去重构呢.不过,还别说,Google就在干这种事,开发全新的操作系统),但并不适用于大型项目和协作开发.尽管Linux的作者Linus极度憎恨C++这样的面向对象的语言,并拒绝C++在Linux内核的使用.但是,Linux的其它开发者也心知肚明,C并不是一切,并且在Linux的各个方面大量使用C++和面向对象的开发模式.知名的KDE桌面就是基于QT来构建的,而QT是对C++的一个扩展,Linux上的大部分可用的应用都是基于QT来构建的,而另一个桌面环境Gnome则使用了GTK绑定,同时也大量使用了面向对象的特性和组件,比如Gobject,Vala.Vala的一个重要使用场景就是Gnome环境的GUI开发.
Vala语言的主要特点:支持lambda表达式;支持对象反射与内省;使用引用计数进行内存管理,计数嵌入在对象内;使用Glib和Gobject的主循环、事件回调系统。
安装
在Ubuntu/Debian下安装很简单,使用命令sudo apt-get install valac,测试valac编译器的版本号,可以输入valac –version命令。 我现在使用的是0.36版本,最新版本应该是0.40 Beta.
HelloWorld程序
class Demo.HelloWorld : GLib.Object {
public static int main(string[] args)
{
stdout.printf("Hello, World\n");
return 0;
}
}
其实在Vala里,类并不是必须的.类名和文件名并不需要一致,并且一个类里允许多个类.
编译运行
编译这个程序使用命令valac hello.vala,编译成功之后生成hello这个可执行程序,运行这个程序,输入结果为: Hello, World
Vala一个比较有趣的地方就是可以直接从Vala源码编译成C源码,比如上面的代码可以使用如下的命令编译成C源码
valac -C ./hello.vala
生成的C源码如下:
/* hello.c generated by valac 0.36.5, the Vala compiler
* generated from hello.vala, do not modify */
#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define DEMO_TYPE_HELLO_WORLD (demo_hello_world_get_type ())
#define DEMO_HELLO_WORLD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEMO_TYPE_HELLO_WORLD, DemoHelloWorld))
#define DEMO_HELLO_WORLD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEMO_TYPE_HELLO_WORLD, DemoHelloWorldClass))
#define DEMO_IS_HELLO_WORLD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEMO_TYPE_HELLO_WORLD))
#define DEMO_IS_HELLO_WORLD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEMO_TYPE_HELLO_WORLD))
#define DEMO_HELLO_WORLD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEMO_TYPE_HELLO_WORLD, DemoHelloWorldClass))
typedef struct _DemoHelloWorld DemoHelloWorld;
typedef struct _DemoHelloWorldClass DemoHelloWorldClass;
typedef struct _DemoHelloWorldPrivate DemoHelloWorldPrivate;
struct _DemoHelloWorld {
GObject parent_instance;
DemoHelloWorldPrivate * priv;
};
struct _DemoHelloWorldClass {
GObjectClass parent_class;
};
static gpointer demo_hello_world_parent_class = NULL;
GType demo_hello_world_get_type (void) G_GNUC_CONST;
enum {
DEMO_HELLO_WORLD_DUMMY_PROPERTY
};
gint demo_hello_world_main (gchar** args, int args_length1);
DemoHelloWorld* demo_hello_world_new (void);
DemoHelloWorld* demo_hello_world_construct (GType object_type);
gint demo_hello_world_main (gchar** args, int args_length1) {
gint result = 0;
FILE* _tmp0_;
_tmp0_ = stdout;
fprintf (_tmp0_, "Hello, World\n");
result = 0;
return result;
}
int main (int argc, char ** argv) {
#if !GLIB_CHECK_VERSION (2,35,0)
g_type_init ();
#endif
return demo_hello_world_main (argv, argc);
}
DemoHelloWorld* demo_hello_world_construct (GType object_type) {
DemoHelloWorld * self = NULL;
self = (DemoHelloWorld*) g_object_new (object_type, NULL);
return self;
}
DemoHelloWorld* demo_hello_world_new (void) {
return demo_hello_world_construct (DEMO_TYPE_HELLO_WORLD);
}
static void demo_hello_world_class_init (DemoHelloWorldClass * klass) {
demo_hello_world_parent_class = g_type_class_peek_parent (klass);
}
static void demo_hello_world_instance_init (DemoHelloWorld * self) {
}
GType demo_hello_world_get_type (void) {
static volatile gsize demo_hello_world_type_id__volatile = 0;
if (g_once_init_enter (&demo_hello_world_type_id__volatile)) {
static const GTypeInfo g_define_type_info = { sizeof (DemoHelloWorldClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) demo_hello_world_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DemoHelloWorld), 0, (GInstanceInitFunc) demo_hello_world_instance_init, NULL };
GType demo_hello_world_type_id;
demo_hello_world_type_id = g_type_register_static (G_TYPE_OBJECT, "DemoHelloWorld", &g_define_type_info, 0);
g_once_init_leave (&demo_hello_world_type_id__volatile, demo_hello_world_type_id);
}
return demo_hello_world_type_id__volatile;
}
可以看出 vala实际是把vala源码编译成GObject的语法,并且加入了很多语法糖.由于vala的这个特性,从而也决定了vala是一种性能比较高的语言.既能获得面向对象的便利,又能获得接近于C语言的性能.
vala可以大量使用glib的库,具有比较强的表现力和较高的开发效率.然而由于其定位的问题,不能在服务端市场分得一杯羹,导致发展极为有限,可惜了这门在我看来,在Linux上开发体验仅次于C++和Java的语言.如果你接触过C++ 17 以上标准的C++,你就会感觉到C++的表现能力和开发效率,已经是一门比较现代化的语言了,并不会比脚本语言低多少.