据我了解,一切都可以用作Tcl数组中的一个关键字。 例如,这个类:
class create MyClass {
variable name
constructor {newName} {
set name $newName
}
method clone {} {
return [MyClass new $name]
}
}
我可以使用此类的实例来引用数组中的数据,如下所示:
set key [MyClass new test]
array set test_array [list $key "data"]
puts $test_array($key)
->data
但是,如果我使用同一对象的另一个实例,则不会检索数据。例如:
set new_key [$key clone]
puts $test_array($new_key)
->no such element in array
据我所知,在TCL中,所有内容都被视为一个字符串,因为引用是不同的,它无法匹配。
尽管如此,我想知道是否有某种方法可以使数组看起来像Java中的内容,例如,应该重写equals
和hashcode
方法来获取所需的行为
答案 0 :(得分:1)
如果没有一些工作,对象不可序列化。转换为字符串时,对象引用返回对象标识符(例如:: oo :: Obj145),而不是对象的内容。
如果我正确地阅读了您的问题,您需要一个基于对象内容的密钥。您需要编写一个方法将对象的数据转换为您希望用作键的字符串。
::oo::class create MyClass {
variable name
constructor {newName} {
set name $newName
}
method toString {} {
my variable name
return $name
}
method clone {} {
return [MyClass new $name]
}
}
set obj [MyClass new test]
set key [$obj toString]
array set test_array [list $key "data"]
puts "$key: $test_array($key)"
#->test: data
set new_obj [$obj clone]
set new_key [$new_obj toString]
puts "$new_key: $test_array($new_key)"
#->test: data
还有一个::oo::copy
函数可用于克隆目的。
答案 1 :(得分:1)
我不确定自己得到了什么,但至少有一部分似乎是能够在索引关联结构时选择不同的方法从对象中获取关键值。在面向对象的语言中,这是相当简单的,因为您只需要覆盖关联结构从索引对象获取键的方式,或覆盖索引对象生成键的方式。
在Tcl中,array
和dict
结构都不是开箱即用的面向对象的。有一些方法可以使用跟踪来覆盖array
成员的索引方式,但它可能变得丑陋和脆弱,除非有人像我一样熟练。因此,在尝试使用了一段时间之后,我为dict
做了一个OO包装。
根据您的描述,这是描述索引生成对象的类。
oo::class create MyClass {
variable name
constructor args {
lassign $args name
}
method data {} {
set name
}
}
包装器只保留一个名为dict
的{{1}},并且还会记住从对象获取键值的方法的名称:默认情况下为data
。 data
可以通过构造函数填充,也可以最初保留为空。
dict
行为:oo::class create MyArray {
variable data method
constructor args {
set data $args
set method data
}
method setKeyMethod m {
set method $m
}
method get key {
dict get $data [$key $method]
}
method set {key value} {
dict set data [$key $method] $value
}
}
更改密钥生成方法的名称。 setKeyMethod
在字典中设置成员,给定具有索引功能的对象和值。 set
在给定具有索引功能的对象的情况下获取字典中的成员。
get
即。生成相同键值的不同对象从字典对象中获取相同的值。
这个结构不存储对索引生成对象的引用,但它很容易实现。由于我无法弄清楚为什么,我真的没有看到一个好方法。