幻想森林

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2736|回复: 0

Genie-01-数据类型

[复制链接]

136

主题

1751

帖子

548

积分

版主

Rank: 7Rank: 7Rank: 7

积分
548
发表于 2010-1-23 12:43:11 | 显示全部楼层 |阅读模式
###数值类型:
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.直接用类型标识
  1. i:int = 5
  2. s:string = "test"
  3. d:double = 3.14
  4. ...
复制代码
2.可以用类型推导的方式
  1. var i = 5
  2. var s = "test"
  3. var d = 3.14
  4. ...
复制代码
另外var还可以同时声明多行多个变量
  1. var
  2.     i = 5
  3.     s = "test"
  4.     d = 3.14
  5.     ...
复制代码

###string类型
  1. init
  2.     s:string = "test"
  3.     print s
复制代码
实际上,genie编译成c代码时是用char*来处理字符串的。也就是说字符串的最后是以0结尾。glib里提供了很多字符串操作。而且如果使用posix库的话,依然可以继续使用c的字符串操作函数,另外还有中文处理...这是个大坑,下次再填吧。

###array类型
  1. init
  2.     a:array of string = {"a", "b", "c"}
  3.     print "%d", a.length //获得数组长度
复制代码
array of string看起来有点怪怪的。不过读起来却很流畅,有点像自然语言一样,不知道是长处还短处了。
array是说数组类型本身,of后面的string是指数组里元素的类型。
实际上编译成c后,array of string是用char**来工作的。
这种声明时还是要手动初始化,不然报错。面倒。强烈希望以后的新版本能自动初始化。
当然也可以在声明中指定数组的大小
  1. init
  2.     a:array of string[3] = {"a", "b", "c"}
  3.     print a[0]
  4.     print a[1]
  5.     print a[2]
复制代码
还可以利用var,用面向对象的方式来声明,这种声明方式就必须指定数组大小。可能是编译器不知道要new多大的空间出来吧。终于可以不用手动初始化了。
  1. init
  2.     var a = new array of int[64]
  3.     print a[0]
复制代码
数组可以用const来修饰,定义成常量数组

###dict字典类型,这东西其实就是关系数组或hash表。
  1. init
  2.     var d = new dict of string,int
  3.     d["Tom"] = 20
  4.     d.set("Joe", 30)
  5.    
  6.     print "%d", d["Tom"]
  7.     print "%d", d["Joe"]
复制代码
在of后面跟两个类型就搞定了,可以自动初始化。
d.get_keys()和d.get_values()可以得key和value的数组

###list列表类型
  1. init
  2.     var l = new list of int
  3.     l.add(1)   
  4.     l.add(2)
  5.     print l[0]
复制代码
也没什么好说的,完全可以当数组操作。

###delegate 委托
  1. delegate dg(a:int):bool
  2.    
  3. def func(a:int):bool
  4.     print "%d", a
  5.     return true
  6. def invoke(d:dg, a:int):bool
  7.     var r = d(a)
  8.     return r
  9. init
  10.     if invoke(func,100) is true
  11.         print "OK!"
  12.     else
  13.         print "Failed!"
复制代码
定义的方法还是比较简单的,可以把定义好的委托直接当一种类型使用。

###namespace命名空间
其实我一直觉得用文件结构来构成包模块什么的是最直观的方式,可惜的是Genie里是用的c++,c#那种方式的。
使用一个命名空间用uses,可以多行
  1. uses
  2.     Posix
  3.     Gtk
复制代码
自己弄命名空间的话
  1. namespace Name1
  2.     def say(s:string)
  3.         print "Name1:" + s
  4.     namespace Name2
  5.         def say(s:string)
  6.             print "Name2:" + s
  7. init
  8.     Name1.say("hello!")
  9.     Name1.Name2.say("hello!")
复制代码

###enum枚举类型
  1. enum test
  2.     a
  3.     b
  4.     c
  5. init
  6.     print "%d", test.a
  7.     print "%d", test.b
  8.     print "%d", test.c
复制代码
如果不手动指定值的话,会自动从0开始,依次往后递增1。
像这个例子中,a=0,后面的b=1,c=2。如果手动指定a=5,那么后面的bc会自动调整为b=6,c=7。

###struct结构体
  1. struct human
  2.     name:string
  3.     age:int
  4. init
  5.     s:human = {"Tom", 20}
  6.     print ("%s\n%d", s.name, s.age)
复制代码
声明后,就能拿来当新类型使用,但遗憾的是不能像d那样往struct里添加方法了。

###可空类型
因为在默认情况下,Genie保证所有的引用点都必须有实际对象,所以就不能为变量赋空值。在声明变量的类型标识后面加上个?号,就可表示这个变量可以为空。
  1. def func(param:string?):string?
  2.     return param
  3. init
  4.     print func(null)
复制代码
实在不太明白这个功能有什么大用处...
有趣的是,官网里的例子还写成了string? param,c方式的声明,根本无法通过编译。
可见这个功能就连他们自己也没怎么用吧。哈哈~

###弱引用
实在不太清楚这是干什么用的。如果是指绕开编译器自己的内存管理,用不从object继承的class不就行了?
先坑在这里吧。

###传递所有权
和C获取指针用*一样,这个操作用#
  1. init
  2.     var s = "a"
  3.     t:string = #s
  4.     print t
复制代码
在这个操作里,t获得s里的值,而s会被清空。还是不明白这是干什么用的...
试了下int类型,不能用#,编译错误。array可以拿到值,不过原来的数组,也就是指针,被彻底清掉了。
list等类型也是差不多的情况。看来#只能用在引用类型。

###指针
主要是Genie用来手动管理内存用的。
  1. class Human
  2.     prop name:string
  3.     def input_name(n:string)
  4.         name = n
  5. init
  6.     tom:Human* = new Human
  7.     tom->input_name("Tom")
  8.     print tom->name
  9.     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块来干别的事情。可以有多个初始化方法。如果不写,编译器会自动创建一个无参的。
  1. class Human:Object
  2.     prop name:string
  3.     init
  4.         print "Human is inititialized"
  5.     final
  6.         print "Human is being destroyed"
  7.     construct(n:string)
  8.         name = n
  9.     construct default()
  10.         name = "noname"
  11.     def input_name(n:string)
  12.         name = n
  13. init
  14.     tom:Human = new Human("Tom")
  15.     joe:Human = new Human.default()
  16.     print tom.name
  17.     print joe.name
复制代码
类成员和方法的修饰
private  私有,和_开头一个效果
abstract 抽象,自己没有实现,但所有子类必须实现这个方法
extern 外部的,可以是定义在c(asm)源文件中的方法,c文件最后一起编译
inline 内联,对于非常小的方法,可以提升性能
virtual 虚拟,可在子方法中重写
override 重写,覆盖父类的同名虚拟方法
static 静态,无须类实例的方法

从Object继承来的类都支持event的写法,这个用起来非常简单
现版本下,不支持带返回值的回调,以及所有的事件永远不能私有。
  1. class Button : Object
  2.     event click()
  3. init
  4.     var b = new Button()
  5.     b.click += def(t)
  6.         print "001"
  7.     b.click += def(t)
  8.         print "002"
  9.     b.click()
复制代码

Genie的接口可以带成员变量,接口也可以从接口继承。
  1. interface ITest
  2.     prop abstract data:int
  3.     def abstract fn()
  4. class CTest : Object implements ITest
  5.     prop data:int
  6.     def fn()
  7.         print "fn"
  8. init
  9.     var t = new CTest()
  10.     t.fn()
复制代码
用类实现接口时,可以从多个接口继承
如:class ListClass : Object implements Collection,List

###判断类型
用isa可以判断出变量的类型,很简单,一看就明了。
  1. init
  2.     var o = new list of string
  3.     if o isa Object do print "a list of string is an object"
  4.     if o isa list of Object do print "a list of string is a list of Object"
  5.     if o isa Gee.Iterable    do print "a list of string implements Iterable"
复制代码

还有不少自己都不能理解的。不过,这部分看起来用处不大的样子。
基本上还是比较容易的。自我感觉,一周之内初步掌握Genie,应该没有什么问题。
难道这就是Genie的官方文档非常之少的理由么?
え~え~お!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|幻想森林

GMT+8, 2024-4-19 06:34 , Processed in 0.017713 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表