来自TCLLIB的包struct :: record提供了模拟记录类型的方法。但是记录实例是当前命名空间中的命令,而不是当前范围中的变量。这意味着记录实例没有垃圾收集。将记录实例的名称传递给过程意味着通过引用而不是通过值传递它,可以将记录的字符串表示作为参数传递,但是它需要在过程中创建另一个实例,配置它并手动删除,这很烦人。我想知道这个设计背后的基本原理。一个简单的替代方案是提供一个lisp风格的记录 - 一组构造,访问和修改过程,并将记录表示为列表。
答案 0 :(得分:3)
从我的观点来看,struct :: record实现是一种oo风格的实现。如果您正在搜索数据样式实现(如lisp),其中命令与数据完全分离,您可能需要查看dict命令。
我会注意到oo风格和数据风格真的不是很好的描述,但它们是我能想到的最好的。
答案 1 :(得分:1)
你当然可以做到“Lisp方式”。
proc mkFooBarRecord {foo bar} {
# Keep index #0 for a "type" for easier debugging
return [list "fooBarRecord" $foo $bar]
}
proc getFoo {fooBarRecord} {
if {[lindex $fooBarRecord 0] ne "fooBarRecord"} {error "not fooBarRecord"}
return [lindex $fooBarRecord 1]
}
# Etc.
效果很好。 (用C语言编写它也可以使它更高效。)请注意,作为通用数据结构,似乎许多人更喜欢Tcl 8.5的字典。有很多种方法可以使用它们;这是一个:
proc mkFooBarRecord {foo bar} {
return [dict create "type" fooBarRecord "foo" $foo "bar" $bar]
}
proc getFoo {fooBarRecord} {
dict with fooBarRecord {
if {$type ne "fooBarRecord"} {error "not fooBarRecord"}
return $foo
}
}
至于整个结构与对象的争论,Tcl倾向于将对象视为具有操作的状态(导致自然呈现为命令,相当重量级的概念),而结构是纯值(并且如此轻量级)。在这方面写了一大块,我真的不知道什么是最好的;我根据具体情况进行工作。如果您使用“结构”,还要考虑是否应该具有代表多个结构中的字段的集合(相当于使用列式存储而不是数据库中的行式存储),因为这样可以在某些结构中实现更高效的处理例。
还考虑使用数据库; SQLite与Tcl集成得非常好,效率相当高,并且如果您不想使用磁盘文件,则支持内存数据库。
答案 2 :(得分:0)
我不会回答你的问题,因为我多年没有使用过Tcl而且我从来没有使用过这种结构,但是我可以给你两条可能的地方,这些地方非常合理,可以提供一个很好的答案。你:
当我使用Tcl时,它们被证明是非常宝贵的资源。