在Tcl数组中使用object作为键

时间:2017-08-31 13:42:20

标签: arrays oop hashmap tcl

据我了解,一切都可以用作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中的内容,例如,应该重写equalshashcode方法来获取所需的行为

2 个答案:

答案 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中,arraydict结构都不是开箱即用的面向对象的。有一些方法可以使用跟踪来覆盖array成员的索引方式,但它可能变得丑陋和脆弱,除非有人像我一样熟练。因此,在尝试使用了一段时间之后,我为dict做了一个OO包装。

根据您的描述,这是描述索引生成对象的类。

oo::class create MyClass {
    variable name
    constructor args {
        lassign $args name
    }
    method data {} {
        set name
    }
}

包装器只保留一个名为dict的{​​{1}},并且还会记住从对象获取键值的方法的名称:默认情况下为datadata可以通过构造函数填充,也可以最初保留为空。

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

即。生成相同键值的不同对象从字典对象中获取相同的值。

这个结构存储对索引生成对象的引用,但它很容易实现。由于我无法弄清楚为什么,我真的没有看到一个好方法。