- 注册时间
- 2004-11-1
- 最后登录
- 2018-4-24
版主
  
- 积分
- 548
|
###数值类型:
bool //布尔类型,值是true或false,只须要1位的空间
char uchar //8位整数或字符
unichar //16位字符
int uint //32位整数
long ulong //64位整数
float double //32位和64位浮点数
###简单的引用类型:
string //utf-8的字符串
array //数组
###高级引用类型
dict //字典
list //列表
dict list这两个类型需要gee的支持。编译时还要用--pkg指定库。
用于mingw32的gee库在http://code.google.com/p/valide/downloads/list可以下到
把里面的三个目录直接拖到c:\vala-0.7.9\中,然后复制压缩包里的share\vala\vapi\gee-1.0.vapi文件到默认的vapi目录下。我的系统是win7,所以这个目录在c:\ProgramData\vala\vapi\
也可以为valac编译器直接指定vapi目录,让它自己去找,
如valac --vapidir=..\share\vala\vapi --pkg gee-1.0 test.gs
###其他类型
delegate //委托
namespace //命名空间
enum //枚举
struct //结构体
###不知道算不算类型的部分,官网是把它放到类型里说的
可空类型
弱引用
传递所有权
指针
###类
=================================================================================
###声明变量有两种方式。
都需要在声明的时候初始化值,或者在声明后,最少赋一次值,不然就报错。
这里有点麻烦,就不能创建时默认初始化么?
1.直接用类型标识- i:int = 5
- s:string = "test"
- d:double = 3.14
- ...
复制代码 2.可以用类型推导的方式- var i = 5
- var s = "test"
- var d = 3.14
- ...
复制代码 另外var还可以同时声明多行多个变量- var
- i = 5
- s = "test"
- d = 3.14
- ...
复制代码
###string类型- init
- s:string = "test"
- print s
复制代码 实际上,genie编译成c代码时是用char*来处理字符串的。也就是说字符串的最后是以0结尾。glib里提供了很多字符串操作。而且如果使用posix库的话,依然可以继续使用c的字符串操作函数,另外还有中文处理...这是个大坑,下次再填吧。
###array类型- init
- a:array of string = {"a", "b", "c"}
- print "%d", a.length //获得数组长度
复制代码 array of string看起来有点怪怪的。不过读起来却很流畅,有点像自然语言一样,不知道是长处还短处了。
array是说数组类型本身,of后面的string是指数组里元素的类型。
实际上编译成c后,array of string是用char**来工作的。
这种声明时还是要手动初始化,不然报错。面倒。强烈希望以后的新版本能自动初始化。
当然也可以在声明中指定数组的大小- init
- a:array of string[3] = {"a", "b", "c"}
- print a[0]
- print a[1]
- print a[2]
复制代码 还可以利用var,用面向对象的方式来声明,这种声明方式就必须指定数组大小。可能是编译器不知道要new多大的空间出来吧。终于可以不用手动初始化了。- init
- var a = new array of int[64]
- print a[0]
复制代码 数组可以用const来修饰,定义成常量数组
###dict字典类型,这东西其实就是关系数组或hash表。- init
- var d = new dict of string,int
- d["Tom"] = 20
- d.set("Joe", 30)
-
- print "%d", d["Tom"]
- print "%d", d["Joe"]
复制代码 在of后面跟两个类型就搞定了,可以自动初始化。
d.get_keys()和d.get_values()可以得key和value的数组
###list列表类型- init
- var l = new list of int
- l.add(1)
- l.add(2)
- print l[0]
复制代码 也没什么好说的,完全可以当数组操作。
###delegate 委托- delegate dg(a:int):bool
-
- def func(a:int):bool
- print "%d", a
- return true
- def invoke(d:dg, a:int):bool
- var r = d(a)
- return r
- init
- if invoke(func,100) is true
- print "OK!"
- else
- print "Failed!"
复制代码 定义的方法还是比较简单的,可以把定义好的委托直接当一种类型使用。
###namespace命名空间
其实我一直觉得用文件结构来构成包模块什么的是最直观的方式,可惜的是Genie里是用的c++,c#那种方式的。
使用一个命名空间用uses,可以多行自己弄命名空间的话- namespace Name1
- def say(s:string)
- print "Name1:" + s
- namespace Name2
- def say(s:string)
- print "Name2:" + s
- init
- Name1.say("hello!")
- Name1.Name2.say("hello!")
复制代码
###enum枚举类型- enum test
- a
- b
- c
- init
- print "%d", test.a
- print "%d", test.b
- print "%d", test.c
复制代码 如果不手动指定值的话,会自动从0开始,依次往后递增1。
像这个例子中,a=0,后面的b=1,c=2。如果手动指定a=5,那么后面的bc会自动调整为b=6,c=7。
###struct结构体- struct human
- name:string
- age:int
- init
- s:human = {"Tom", 20}
- print ("%s\n%d", s.name, s.age)
复制代码 声明后,就能拿来当新类型使用,但遗憾的是不能像d那样往struct里添加方法了。
###可空类型
因为在默认情况下,Genie保证所有的引用点都必须有实际对象,所以就不能为变量赋空值。在声明变量的类型标识后面加上个?号,就可表示这个变量可以为空。- def func(param:string?):string?
- return param
- init
- print func(null)
复制代码 实在不太明白这个功能有什么大用处...
有趣的是,官网里的例子还写成了string? param,c方式的声明,根本无法通过编译。
可见这个功能就连他们自己也没怎么用吧。哈哈~
###弱引用
实在不太清楚这是干什么用的。如果是指绕开编译器自己的内存管理,用不从object继承的class不就行了?
先坑在这里吧。
###传递所有权
和C获取指针用*一样,这个操作用#- init
- var s = "a"
- t:string = #s
- print t
复制代码 在这个操作里,t获得s里的值,而s会被清空。还是不明白这是干什么用的...
试了下int类型,不能用#,编译错误。array可以拿到值,不过原来的数组,也就是指针,被彻底清掉了。
list等类型也是差不多的情况。看来#只能用在引用类型。
###指针
主要是Genie用来手动管理内存用的。- class Human
- prop name:string
- def input_name(n:string)
- name = n
- init
- tom:Human* = new Human
- tom->input_name("Tom")
- print tom->name
- delete tom
复制代码 在类型后加个*用来创建其指针
和c++一样,用->来访问类指针中的成员和对象了...
显式的new和delete
###类
Genie中的类的所有成员变量,没有用_或private修饰的话,默认是公开的。
比如上面的那个Human类,编译器自动为成员变量name加上了公开的set_name,get_name方法来读写它。
声明成员变量要用prop来修饰。
创建实例用new
可以包含:
1.init语句块用来初始化类,但不可以加参数,这个语句块依赖GLib.Object,如果类不从Object继承,则不可以用init语句块,final和construct没有这个限制。
2.final语句块用来销毁类,同样不可以加参数。
3.construct语句块被用来构建类,但只限于操作类自己的成员变量,因为有init块来干别的事情。可以有多个初始化方法。如果不写,编译器会自动创建一个无参的。- class Human:Object
- prop name:string
- init
- print "Human is inititialized"
- final
- print "Human is being destroyed"
- construct(n:string)
- name = n
- construct default()
- name = "noname"
- def input_name(n:string)
- name = n
- init
- tom:Human = new Human("Tom")
- joe:Human = new Human.default()
- print tom.name
- print joe.name
复制代码 类成员和方法的修饰
private 私有,和_开头一个效果
abstract 抽象,自己没有实现,但所有子类必须实现这个方法
extern 外部的,可以是定义在c(asm)源文件中的方法,c文件最后一起编译
inline 内联,对于非常小的方法,可以提升性能
virtual 虚拟,可在子方法中重写
override 重写,覆盖父类的同名虚拟方法
static 静态,无须类实例的方法
从Object继承来的类都支持event的写法,这个用起来非常简单
现版本下,不支持带返回值的回调,以及所有的事件永远不能私有。- class Button : Object
- event click()
- init
- var b = new Button()
- b.click += def(t)
- print "001"
- b.click += def(t)
- print "002"
- b.click()
复制代码
Genie的接口可以带成员变量,接口也可以从接口继承。- interface ITest
- prop abstract data:int
- def abstract fn()
- class CTest : Object implements ITest
- prop data:int
- def fn()
- print "fn"
- init
- var t = new CTest()
- t.fn()
复制代码 用类实现接口时,可以从多个接口继承
如:class ListClass : Object implements Collection,List
###判断类型
用isa可以判断出变量的类型,很简单,一看就明了。- init
- var o = new list of string
- if o isa Object do print "a list of string is an object"
- if o isa list of Object do print "a list of string is a list of Object"
- if o isa Gee.Iterable do print "a list of string implements Iterable"
复制代码
还有不少自己都不能理解的。不过,这部分看起来用处不大的样子。
基本上还是比较容易的。自我感觉,一周之内初步掌握Genie,应该没有什么问题。
难道这就是Genie的官方文档非常之少的理由么? |
|