我要指出的是,名为StorageClass的语法规则与语言中语义上的存储类之间存在很大差异。语法规则与解析有关,而不是与编译的语义阶段有关。
首先,第 8 章的TDPL明确涉及类型限定符(Walter 使用了术语类型构造函数)。D中只有3个:
const
不可变
共享
他们三个都是他们修改的类型的一部分。对于诸如ref
.
inout
TDPL 称之为“通配符限定符”,因此它是类型限定符的占位符,而不是真正的类型限定符或存储类。
现在,关于什么是存储类,我从 TDPL 中引用两句:
每个函数参数(在上面base
的exponent
示例中)除了它的类型之外,还有一个可选的存储类,它决定了在调用时将参数传递给函数的方式。
(从第 6 - 7 页开始)
尽管static
与将参数传递给函数无关,但在这里讨论它是合适的,因为就像应用于数据一样ref
,是一个存储类,表示有关如何存储数据的详细信息的指示。static
(从第 137 页开始)
此外,关于 C 中的存储类,有这句话似乎在网上找到的 C 中的存储类的解释中使用 了很多:
存储类定义了 C 程序中变量和/或函数的范围(可见性)和生命周期。
存储类对变量的类型没有影响,只是它的存储方式。不幸的是,我找不到 D 中存储类的确切列表,人们对存储类这个术语非常自由,即使它不适用也使用它。几乎所有应用于类型保存访问修饰符的属性似乎都被称为存储类,这取决于谁在说话。但是,有一些是毫无疑问的存储类:
枚举(当用作清单常量时)
extern
lazy
out
ref
scope
static
lazy
, out
, andref
可用于修改函数参数并指示它们的传递方式,而enum
andstatic
用于指示变量的存储方式(enum
在使用而不是实际变量)。extern
影响联动。
in
是一个混合体,因为它是 的同义词scope const
,而 whilescope
是一个存储类,const
是一个类型限定符。
在线文档也将auto
andsynchronized
称为存储类,尽管我不知道基于什么。auto
就像inout
它是一个占位符(在这种情况下是一个类型的占位符而不是一个类型限定符),因此没有说明一个类型是如何存储的,所以我不会想到它会是一个存储类。synchronized
不修改变量而是修改类。
__gshared
可能也是一个存储类,虽然它有点有趣,因为它或多或少地做了shared
(这是一个类型限定符)所做的,但它不是类型的一部分。
除此之外,我不知道。synchronized
被列为存储类的事实意味着其他一些(例如final
)可能是,但(例如synchronized
)它们与变量的存储或链接方式无关。所以,我不知道如何将它们视为存储类。
不过,我会在新闻组上询问,看看是否可以获得更明确的列表。
编辑:似乎在 D 中没有明确的官方存储类列表。该术语用于几乎所有不影响其类型的变量声明中使用的属性(即不是类型限定符)。似乎 Walter 和 Andrei 倾向于在类型限定符上强调哪些属性实际上会影响变量的类型,但术语存储类并没有被赋予接近相同的重要性级别并且最终被使用非正式的,而不是任何严格的定义。