gpt4 book ai didi

tcl - 类的真正命名空间

转载 作者:行者123 更新时间:2023-12-04 05:01:19 31 4
gpt4 key购买 nike

在构造函数、析构函数或方法中,我可以找出类是在哪个命名空间中创建的,所以我可以调用 card在我的其他类(class)中,而不是将其硬编码为 blackjack::card ?

namespace eval blackjack {

oo::class create card {
...
}

oo::class create deck {
constructor {} {
my variable cards
set cards {}
for {set suit 0} {$suit < 4} {incr suit} {
for {set value 0} {$value < 13} {incr value} {
lappend cards [blackjack::card new $suit $value]
}
}
}
...
}

}

最佳答案

选项 0:完全限定名称

你已经知道这一点,这也是我几乎总是在做的事情,因为它直接而简单。 (这是“选项 0”,因为它没有提出问题。)

选项 1:uplevel
你可以这样做:

lappend cards [uplevel 1 [list card new $suit $value]]

但这取决于 deck new从正确的命名空间调用。

选项2:类名手术

如果我们假设两个类在同一个命名空间中:
constructor {} {
set cardClass [namespace qualifiers [self class]]::card
# ...
lappend cards [$cardClass new $suit $value]
# ...
}

选项 3:扩展对象的 namespace path
如果您添加到对象的路径(注意:现在必须在构造函数中基于每个对象完成),那么您可以简单地引用另一个类:
constructor {} {
namespace path [list {*}[namespace path] ::blackjack]
# ...
lappend cards [card new $suit $value]
# ...
}

这里要注意的主要事情是 TclOO 设置了一个重要的默认值 namespace path (你认为 nextself 来自哪里?)

选项 4:制作命令链接

您还有另一种选择,那就是使用 namespace exportnamespace import制作命令链接。

首先,从 ::blackjack导出相关类命名空间:
namespace eval ::blackjack {
namespace export card; # You probably want to export “deck” as well

# ...
}

然后,在构造函数中进行导入:
constructor {} {
namespace import ::blackjack::card
# ...
lappend cards [card new $suit $value]
# ...
}

选项 5:在 deck 中创建一个特殊的子类实例

这个很棘手!
constructor {} {
oo::class create card {superclass ::blackjack::card}
# ...
lappend cards [card new $suit $value]
# ...
}

这也意味着卡片会在牌组消失时自动删除;您不需要在析构函数中销毁它们(因为它们的实际类将被自动删除,并且会杀死实例)。这可能是也可能不是您需要的。 (它确实提供了一种对 UML 组合关系建模的好方法;TDBC 在内部使用它的变体来将语句与连接和结果集与语句相关联。)

关于tcl - 类的真正命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16131296/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com