使用TclOO在对象创建中创建vs新建

使用TclOO在对象创建中创建vs新建,tcl,Tcl,我正在研究TclOO,发现我们可以使用create或new创建对象。 使用create我们可以提供定制的名称,而使用new则是计算机生成的 #!/bin/bash #\ exec tclsh8.6 $0 $@ ::oo::class create calc { method add { a b } { return [ expr {$a+$b} ] } } calc create c; set t [ calc new ] #

我正在研究
TclOO
,发现我们可以使用
create
new
创建对象。 使用
create
我们可以提供定制的名称,而使用
new
则是计算机生成的

#!/bin/bash
#\
exec tclsh8.6 $0 $@

::oo::class create calc {
        method add { a b } {
                return [ expr {$a+$b} ]
        }
}

calc create c;
set t [ calc new ]

# Both serves the same purpose here
puts [ c add 3 4 ] 
puts [ $t  add 1 2 ] 

这仅仅是编译器为开发人员提供的对象命名便利吗?另外,如果我更喜欢
new
而不是
create
new
create
之间的唯一区别就是
create
允许您指定要使用的名称,
new
为您提供一个新名称。某些类型的对象(特别是类)隐藏了它们的
新方法
,因此强烈建议您只创建命名实例-考虑到人们使用类的方式,这在实践中很有意义-但这只是隐藏,如果需要,您可以覆盖它:

oo::define oo::class {
    export new
}
如果你不在乎名字,只想让它与其他东西不同,就可以使用
new
。这是基本的经验法则

单身汉 使用
create
创建其他OO系统可能使用单例的实例也很完美。还有什么比给他们一个你能控制的好名字更独特的呢

寿命管理 我所知道的另一个主要场景是,当您希望将一个对象的寿命绑定到另一个对象时,使用
create
更有用。在这种情况下,在另一个上下文中创建对象将把对象句柄放在容器的命名空间中,并在删除容器时自动触发删除:

oo::class create InsideThing {
    constructor {} {
        puts "Made a [self] that is an InsideThing"
    }
    destructor {
        puts "Deleted a [self] that is an InsideThing"
    }
}
oo::class create Container {
    constructor {} {
        puts "Created a [self] that is a Container"
        InsideThing create inner1
        InsideThing create inner2
    }
    destructor {
        puts "Deleted a [self] that is a Container"
    }
}

set c [Container new]
puts "Do stuff..."
$c destroy
如果运行该代码,则会得到以下结果:

Created a ::oo::Obj13 that is a Container Made a ::oo::Obj13::inner1 that is an InsideThing Made a ::oo::Obj13::inner2 that is an InsideThing Do stuff... Deleted a ::oo::Obj13 that is a Container Deleted a ::oo::Obj13::inner1 that is an InsideThing Deleted a ::oo::Obj13::inner2 that is an InsideThing 创建了一个容器::oo::Obj13 制作了一个::oo::Obj13::inner1,它是一个InsideThing 制作了一个::oo::Obj13::inner2,它是一个InsideThing 做些事情。。。 删除了作为容器的a::oo::Obj13 删除了作为InsideThing的a::oo::Obj13::inner1 删除了作为InsideThing的a::oo::Obj13::inner2 这种技术在TDBC中广泛用于在结果集和语句的容器(分别是语句和连接)上下文中管理结果集和语句

Tk Megawidgets
最后,如果您使用TclOO创建Tk MegaWidget,您肯定会使用
create
,但会以重写形式,因为Tk Widget必须具有以
开头的非限定名称,并且具有特定的具体层次结构,强烈建议MegaWidget遵循相同的模式。因为名称在这种情况下非常重要,
new
是错误的方法;最好从
创建
开始。Tk 8.6有一些支持类(未公开描述,但内部用于某些对话框),使这类事情变得更容易:
Tk::Megawidget
Tk::MegawidgetClass
。有关详细信息,请查看Tk 8.6发行版。

谢谢Donal。真的很有帮助,从创造者那里得到解释也很有趣。