【发布时间】:2020-06-18 11:33:30
【问题描述】:
我需要知道 Tcl 中一些变量的数据类型。例如,有三个变量:
set a 10
set b { I love Tcl }
set c "Hello"
假设我不知道他们的类型。但我需要知道这一点才能进一步开展我的工作。那么,我将如何确定 - 在上面的示例中 -
-
a是一个整数 -
b是一个列表 -
c是一个字符串
【问题讨论】:
-
我只需要知道变量的类型,不执行任何功能
我需要知道 Tcl 中一些变量的数据类型。例如,有三个变量:
set a 10
set b { I love Tcl }
set c "Hello"
假设我不知道他们的类型。但我需要知道这一点才能进一步开展我的工作。那么,我将如何确定 - 在上面的示例中 -
a 是一个整数b 是一个列表c 是一个字符串【问题讨论】:
Tcl 的变量根本没有数据类型。它们都可以保持任何值。
Tcl 的值有类型,但是类型系统在很大程度上隐藏在脚本中,人们说一切都是字符串是正常的(因为字符串是 Tcl 中所有其他值类型的超类型)。您的代码也不应该依赖于值的类型,只要您拥有的值可以被强制转换为正确的类型,这是由 Tcl 的各种操作自动完成的(例如,列表操作强制列表类型、算术运算强制转换为数字类型)。最近的这种强制被缓存在值中;这使得大多数操作实际上相当快。
您可以使用tcl::unsupported::representation 命令查看当前Tcl 系统对值类型的看法,这是一个仅用于调试的操作。请注意,类型可能并不总是您所期望的;系统对您的打字有不同的概念。
set a 10
set b { I love Tcl }
set c "Hello"
# Print the representations; these are all of LITERALS
puts [tcl::unsupported::representation $a]
puts [tcl::unsupported::representation $b]
puts [tcl::unsupported::representation $c]
# Now actually use the values in ways that do type forcing...
set a [expr {$a << 0}]
set b [lrange $b 0 end]
set c [string range [append c \u1234] 0 end-1]
# Print the representations again
puts [tcl::unsupported::representation $a]
puts [tcl::unsupported::representation $b]
puts [tcl::unsupported::representation $c]
示例输出(来自我的机器):
value 是一个纯字符串,引用计数为 4,对象指针位于 0x7fad2df273d0,字符串表示为“10” value 是一个纯字符串,引用计数为 4,对象指针位于 0x7fad2df26e30,字符串表示“我爱 Tcl” value 是一个纯字符串,引用计数为 4,对象指针位于 0x7fad2df29860,字符串表示“Hello” value 是一个 int,引用计数为 2,对象指针位于 0x7fad2df2a3a0,内部表示 0xa:0x7fad2df29a40,无字符串表示 value 是一个引用计数为 2 的列表,对象指针位于 0x7fad2df27790,内部表示 0x7fad30826510:0x0,无字符串表示 value 是一个引用计数为 2 的字符串,对象指针位于 0x7fad2df29440,内部表示 0x7fad30826210:0x0,无字符串表示最后一行特别奇怪,但这是因为我们已经从 UTF-8 转换为(大约)UTF-16。
同样,不要让您的代码类型依赖。 tcl::unsupported 命名空间中命令的行为和格式如有更改,恕不另行通知。值的表示如有更改,恕不另行通知(并且不是 Tcl API 的一部分)。如果你正在编写 C 代码来处理表示,你可以这样写:
【讨论】:
llength $a 强制写入列表表示中a。你真的不能依赖具有特定类型的 Tcl 值。