Closed. This question needs to be more
focused。它当前不接受答案。
想要改善这个问题吗?更新问题,使它仅关注
editing this post的一个问题。
3年前关闭。
Improve this question
我今天了解到,动态类型的编程语言在运行时进行类型检查,而静态类型的语言在编译时进行类型检查(如果我错了,请纠正我)。我想知道的是,在运行时如何动态键入语言找出类型以及它如何工作?而且动态类型语言也称为值类型语言,这意味着在动态类型语言中,类型与值相关联?
作为我的初学者,我的问题将不是一个好问题,请尝试从我的角度思考,我才刚刚开始,在任何地方都找不到这个答案。
更新来自
Type System上的Wikipedia页面
Implementations of dynamically type-checked languages generally associate each runtime object with a "type tag" (i.e. a reference to a type) containing its type information. This runtime type information (RTTI) can also be used to implement dynamic dispatch, late binding, downcasting, reflection, and similar features.
现在什么是类型标记,它是如何工作的,我的意思是如果您可以告诉我它在内存中的表示方式?
这取决于实现。这是有关实现可能如何决定代表值的三个粗略示例。
关于术语的注释:我将使用“值”一词来讨论作为参数传递给函数,放入字段等的位。在许多情况下,值可能是或包含指向附加内存的指针别处。
1:带类型标签头的指针
在此实现中,值只是指向内存中对象的指针,并且每个对象在相同的偏移量处都有一个“类型标签”,用于说明其类型。它可以是简单的枚举,也可以是指向
某种“元级”。
例如,整数将由指向具有两个字段的对象的指针表示:第一个包含类型标签INTEGER
,第二个包含整数值。当谈论简单的原始数据(例如整数)时,这称为“盒装”表示。
优点是简单。装箱整数的不利之处在于,每个算术运算1)都要进行额外的指针间接操作,而2)需要为结果分配一个对象。通常这真的很慢。
Java虚拟机将此表示形式用于所有类类型的变量和字段。这就是int
快而Integer
慢(除非进行优化等)的原因。
2:两个字
另一种可能的表示形式是使用两个单词来表示每个值。第一个是类型标记,第二个是立即数(对于整数, bool 值,字符等类型)或指针(对于字符串,对象,数组等)。
这样就消除了与装箱整数等相关的分配和内存间接问题,但它使值表示形式增加了两倍,这很浪费。
3:带标记位的一个字
第三种表示形式通过将类型标记和值压缩到单个单词中来“优化”第二种表示形式。如果所有对象都分配了32位对齐,则每个有效指针都以2个零位结尾。 (或3表示64位对齐,等等。)这些位可用于区分非常少的基本类型。例如,这是一个标记系统:
xxxxxx00
表示整数值xxxxxx
(带符号扩展名)。此表示形式中的整数称为“fixnums”。 vvvvvv01
表示vvvvvv
解释为另一种较小的值(如 bool 值,“null”,字符等) pppppp10
表示地址为pppppp00
的对象(该对象以更详细的类型头开头)与上面的表示形式2一样,此表示形式方案也避免了对(大多数)小数据进行装箱,但由于值仍由单个单词表示,因此避免了膨胀。它需要与垃圾收集器进行某种程度的合作(以识别并遵循指针),但是2也是如此。
对于像Scheme这样的语言,它具有无限制大小的整数以及其他类型的数字,例如“flonums”(浮点数)和“ratnums”(精确有理数或小数),像
a+b
这样的算术运算像这:
if a and b are both fixnums:
add a and b directly
on overflow, jump to the general addition function
otherwise, that's the result
otherwise, jump to the general addition function
通用加法功能只是遍历所有情况,在必要时找出晋升情况,并针对给定的数字进行适当的工作。但是,如果大多数时间
a
和
b
是fixnums,则计算是按行进行的,而且速度很快。
尽管操作(原始算术,对象字段获取等)的检查和补偿标记位变得有些复杂,但这种表示方式既快速又紧凑。这种方法的一个缺点是,如果您以典型的类型化,安全的语言(例如Java,C#,ML等)编写解释器/VM,则通常无法使用它。类型系统不允许您将整数转换成指针。您可以在C语言中执行此操作,这是不安全的。
该表示思想的另一个变体是“NaN编码”:大约有2 ^ 51个位模式,它们表示“非数字”作为IEEE double 浮点数。为什么不自己代表有效的浮点数,而将其他值打包到NaN空间中呢?
以下是一些引用资料:
Data representations in Larceny, an implementation of Scheme(上面#3的版本)一个blog post,它更详细地介绍了相同的想法