rednaxela 发表于 2008-5-9 20:14:34

保存结构化数据的问题

不厚道引用群聊天记录:
全局变量D 20:32:27
头大了,一定得去学类的用法了...像这么用数组我会死OTL
全局变量D 13:36:16
 但是呢、KAG 因为是基于 <kw>TJS2</kw> 这一脚本语言的系统、KAG 的変数实际上就是 TJS2 の変数,可以发挥很强大的作用。(译注:口胡,给我一个能保存的数据类再说……)<r/><=在翻译中散发怨念
ミリアルド 13:41:26
能保存的数据类?
ミリアルド 13:41:34
在F里面加个类就好
全局变量D 13:41:53
不行...我试过用f.var=new XXX()
全局变量D 13:42:07
结果保存不能...f.var倒是存在,就是没有值

这是挺蹊跷的,所以刚才稍微看了下是怎么回事。

有时候我们希望能够在存档文件里保存些结构化的数据,而不只是简单的字符串或者数字。但是你会发现,f、sf里只能保存数字、字符串、数组或者字典,却不能保存一般的Object。为什么会这样的呢?

从Initialize.tjs可以看到,f、sf分别是kag.flags、kag.sflags的别名。它们本身都是字典(或者叫关联数组)。于是我们可以对关联数组做个测试,看看问题是不是出在它上面:
class TestSave {
    var value = 0;
   
    function TestSave(initVal) {
      value = initVal;
    }
   
    property Value {
      getter() { return value; }
      setter(newValue) { value = newValue; }
    }
}
var vfx = %[ "cool" => new TestSave(1) ];
(Dictionary.saveStruct incontextof vfx)("./test.txt", "");
执行这段代码后,可以看到test.txt里的内容是:
%[   
"cool" => null /* (object) "(object 0x01702668:0x01702668)" */
]
也就是说虽然要保存的对象本身并不是null(如果是null的话,保存时不会写出object地址的注释),但是却被保存为了null。所以很明显,向f或者sf写入对象的话肯定也是一样的结果。

具体内部是怎么实现的请看这里:使用Dictionary保存数据的功能在引擎里的内部实现

结论是:用Dictionary或者Array来保存数据时,只有字典、数组或者null能被正确保存;其它Object类型的对象都被保存为了null。

回到D大的问题:在不适合用数组的地方用数组会很头疼,怎么办?

首先,什么情况下适合使用数组?一般,人们习惯在数组里保存同质的数据,例如说要么都是字符串,要么都是整形数字,等等。即便保存的内容的类型不相同,至少同一个数组里放的东西的“意义”要相近,否则很容易混乱。

接下来,假如要保存异质数据的时候怎么办呢?在允许用户自定义数据类型(UDT)的语言里,一般都有记录(record)或者结构(struct)类型来解决这个问题。在面向对象的语言里直接用类(class)也可以。它们都可以定义异质的成员,于是可以把一些原本不相关的数据集合在一起,例如:
struct Person { boolean sex; string name; }
不过这样能定义的成员个数是固定的;一旦定义,成员的个数就不能改变了。
而且D大需要的是能被KAG自动保存的、异质的数据集合。那就只有一个选择了:使用字典(Dictionary)。

KAG是允许嵌套使用字典的。所以在f或者sf里保存字典也是可以的。假如我要保存某个人物信息的话:
var personInfo = %[
    "name" => "FX",
    "sex" => "male"
]; // 创建字典

personInfo.name = "rednaxela"; // 可以改变内容

f.personInfo = personInfo if f.personInfo == void; // 可以放到f或者sf里
// 也可以正确保存
某种意义上说跟使用“类”也没啥区别……(考虑到对象模型的语义)

CountD 发表于 2008-5-9 22:37:37

嗯,实际上今天刚想到字典这东西,但是对TJS不熟悉所以...
感谢讲解&gt;v&lt;
...这么说我要重写好大一段程序TVT
页: [1]
查看完整版本: 保存结构化数据的问题