Arrays 将对象用作Tcl数组中的键

Arrays 将对象用作Tcl数组中的键,arrays,oop,hashmap,tcl,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_a

据我所知,在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
方法应该被重写以获得所需的行为。

如果不做一些工作,对象是不可序列化的。对象引用在转换为字符串时返回对象标识符(例如::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
函数。

如果不做一些工作,对象是不可序列化的。对象引用在转换为字符串时返回对象标识符(例如::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
函数。

我不确定我是否得到了您想要的,但它至少有一部分似乎是在索引关联结构时能够选择不同的方式从对象获取键值。在完全面向对象的语言中,这相当简单,因为您只需要覆盖关联结构如何从索引对象获取键,或者覆盖索引对象如何生成键

在Tcl中,
数组
dict
结构都不是现成的面向对象的。有很多方法可以使用跟踪覆盖
数组
成员的索引方式,但它可能变得丑陋而脆弱,除非像我这样熟练的人尝试。所以,在尝试了一段时间之后,我为一个
dict
做了一个OO包装

根据您的描述,下面是描述索引生成对象的类

oo::class create MyClass {
    variable name
    constructor args {
        lassign $args name
    }
    method data {} {
        set name
    }
}
包装器只保留一个名为
data
dict
,还记得从对象获取键值的方法的名称:默认情况下
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
更改密钥生成方法的名称<代码>集在给定可索引对象和值的情况下,设置字典中的成员
get
获取字典中的成员,给定一个支持索引的对象

% MyArray create test_array
::test_array
% set key [MyClass new test]
::oo::Obj64
% test_array set $key foo
test foo
% set key2 [::oo::copy $key]
::oo::Obj65
% test_array get $key2
foo
即,产生相同键值的不同对象从dictionary对象获得相同的值


此结构不存储对索引生成对象的引用,但它很容易做到这一点。因为我不知道为什么,所以我真的看不到一个好方法。

我不确定我是否得到了您想要的,但至少有一部分似乎是在索引关联结构时能够选择不同的方法从对象获取键值。在完全面向对象的语言中,这相当简单,因为您只需要覆盖关联结构如何从索引对象获取键,或者覆盖索引对象如何生成键

在Tcl中,
数组
dict
结构都不是现成的面向对象的。有很多方法可以使用跟踪覆盖
数组
成员的索引方式,但它可能变得丑陋而脆弱,除非像我这样熟练的人尝试。所以,在尝试了一段时间之后,我为一个
dict
做了一个OO包装

根据您的描述,下面是描述索引生成对象的类

oo::class create MyClass {
    variable name
    constructor args {
        lassign $args name
    }
    method data {} {
        set name
    }
}
包装器只保留一个名为
data
dict
,还记得从对象获取键值的方法的名称:默认情况下
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
更改密钥生成方法的名称<代码>集在给定可索引对象和值的情况下,设置字典中的成员
get
获取字典中的成员,给定一个支持索引的对象

% MyArray create test_array
::test_array
% set key [MyClass new test]
::oo::Obj64
% test_array set $key foo
test foo
% set key2 [::oo::copy $key]
::oo::Obj65
% test_array get $key2
foo
即,产生相同键值的不同对象从dictionary对象获得相同的值


此结构不存储对索引生成对象的引用,但它很容易做到这一点。因为我不知道为什么,所以我真的看不到一个好方法。

设置键的值不是名称,而是唯一的对象标识符。我回家后会看看我能不能做点什么,除非有人比我强。是的,我明白。这就是为什么我在寻找一个解决方案,它将调用一个方法而不是引用。我期待着您的建议。您设置密钥的值不是名称,而是唯一的对象标识符。我回家后会看看我能不能做点什么,除非有人比我强。是的,我明白。这就是为什么我在寻找一个解决方案,它将调用一个方法而不是引用。我期待着您的建议。我考虑过这个解决方案。然而,我正在寻找一个解决方案,该解决方案将对象的引用也保留在密钥中。我一点也不确定这在Tcl是可能的,但是。。。谢谢你的
::oo::copy
我想到了这个解决方案