我在其他地方读过,可以使用关键字set在TCL中创建常量。但是,当我查看math包的源代码时,我发现math常量是以不同的方式声明的。请参阅下面的code:
package provide math::constants 1.0.1
# namespace constants
# Create a convenient namespace for the constants
#
namespace eval ::math::constants {
#
# List of constants and their description
#
variable constants {
pi 3.14159265358979323846 "ratio of circle circumference and diameter"
e 2.71828182845904523536 "base for natural logarithm"
ln10 2.30258509299404568402 "natural logarithm of 10"
phi 1.61803398874989484820 "golden ratio"
gamma 0.57721566490153286061 "Euler's constant"
sqrt2 1.41421356237309504880 "Square root of 2"
thirdrt2 1.25992104989487316477 "One-third power of 2"
sqrt3 1.73205080756887729533 "Square root of 3"
radtodeg 57.2957795131 "Conversion from radians to degrees"
degtorad 0.017453292519943 "Conversion from degrees to radians"
onethird 1.0/3.0 "One third (0.3333....)"
twothirds 2.0/3.0 "Two thirds (0.3333....)"
onesixth 1.0/6.0 "One sixth (0.1666....)"
huge [find_huge] "(Approximately) largest number"
tiny [find_tiny] "(Approximately) smallest number not equal zero"
eps [find_eps] "Smallest number such that 1+eps != 1"
}
namespace export constants print-constants
}
答案 0 :(得分:2)
- “变量常量”是字典吗?看来是这样。但是哪个关键字是变量?
不是(或者是,而是偶然)。它定义的每个事物在定义中都有三个 words ,字典中每个映射条目严格都有两个单词。
variable
命令记录在:https://www.tcl-lang.org/man/tcl8.6/TclCmd/variable.htm
- 为什么我们同时需要
namespace eval
和namespace export
?我的意思是为什么不只说一次namespace ::math::constants
而就这样呢?- 我们为什么需要此行
namespace export constants print-constants
?
namespace export
定义了哪些命令是从名称空间导出的,即哪些命令可以由其他地方namespace import
使用。不假设所有命令都已导出。不假设名称空间会导出与其自身名称相同的命令。不会导出变量(但是可以实现类似的效果;在命名空间变量之间很少这样做)。
如果您在namespace ensemble
中使用默认值,或者继续使用TclOO,则此更改。那些 do 做(记录!)默认假设。
变量和命令完全是不同的东西。它们使用不同的名称空间(即,每个名称空间中具有不同的哈希表),并且不能混淆。 math::constants
程序包提供了执行其他操作的命令,但这只是该程序包的一个功能,并不通用。
许多名称空间从不导出任何命令。没关系的始终可以使用完全限定的名称来访问命令和变量。
- 为什么不只使用TCL
set
命令创建常量?
您可以在全局名称空间中。按照惯例,通用库会尝试将其留给Tcl本身(尽管Tcl还保留了一些名称空间,尤其是::tcl
)和应用程序,即代码。
但是在非根名称空间中,出于我认为最好将其视为错误的严重丑陋原因,最好使用variable
命令创建变量。从技术上讲,这不是错误,而是变量解析的极端结果,我非常讨厌。 (我认为它会从Tcl 9.0中消失。)用可能的另一种方式来做,但是可能不行,而且您确实不希望仅使用 might < / em>在生产中工作。当在全局名称空间中存在一个具有相同名称的现有变量时,就会发生问题……而仅仅是UGH!
set
和variable
在此方面的差异是Tcl自己的软件包中存在许多错误的原因。
- 是真的我们不能在TCL中真正拥有常量(例如C中的const关键字),并且所有内容都可以重新定义为我们想要的东西吗?这不会对这种语言造成安全性问题吗?
通常来说,这没有安全性问题。原因有很多:
unset
变量并且不能真正被阻塞;例如,如果删除包含的名称空间,则必须起作用。一旦可以删除,就不能保证它是常量。其他语言中常量的主要用途是什么?嗯,有各种类型的枚举(在Tcl中,您将使用项目名称或名称列表,但都无法将其映射为其他名称),然后有您所描述的特殊常量。这些通常不是安全令牌,而是如果有人将pi
设置为3.0
,那么他们只会得到错误的答案。在他们身上!
Tcl不会阻止您在自己的解释器中引起问题。您确实可以执行诸如替换while
和foreach
之类的操作(在某些情况下这样做很有用)。但是,如果您弄错了,您所要做的就是给自己带来麻烦。我曾经决定为所有按其操作命名的按钮制作图标图像,然后简短地想知道为什么每次对open
文件的调用都停止工作。哦,很好。
但是一个解释器中的操作不能会影响另一解释器中发生的事情,除非另一个解释器给予了许可(或者这是父解释器中的操作影响了它的一个或多个子代)。这就是安全域的障碍。不要在受信任的上下文中评估不受信任的代码。只是不要。