动态类型语言如何运作?

时间:2017-01-08 13:40:17

标签: types programming-languages type-systems dynamic-typing static-typing

我今天了解到动态类型编程语言在运行时进行类型检查,而不是在编译时这样做的静态类型语言。(如果我错了,请纠正我)。我想知道的是,在运行时动态类型语言如何找出类型以及它是如何工作的?动态类型语言也被称为值类型语言,在动态类型语言的情况下,类型与值相关联是什么意思?

由于我是初学者,我的问题会让你们中的一些人认为不是一个好问题,请尝试从我的角度思考,我刚刚开始,我没有在任何地方找到这个答案。

更新

来自维基百科页面Type System

  

动态类型检查语言的实现通常将每个运行时对象与包含其类型信息的“类型标记”(即对类型的引用)相关联。此运行时类型信息(RTTI)还可用于实现动态分派,后期绑定,向下转换,反射和类似功能。

现在什么是类型标签以及它是如何工作的,我的意思是,如果你能告诉我它在内存中是如何表现的?

2 个答案:

答案 0 :(得分:3)

由实施决定。以下是实现可能决定如何表示值的三个粗略示例。

关于术语的说明:我将使用“值”一词来讨论作为函数的参数传递的位,放入字段等等。在许多情况下,值可能是或包含指针在其他地方增加记忆。

1:带有类型标记头的指针

在此实现中,值只是指向内存中对象的指针,并且每个对象都具有相同偏移量的“类型标记”,表示它是什么类型的东西。它可以是简单的枚举或指向a的指针 某种“元级”。

例如,一个整数将由一个指向具有两个字段的对象的指针表示:第一个包含类型标记INTEGER,第二个包含整数值。在谈论像整数这样的简单原始数据时,这被称为“盒装”表示。

优点是简单。拳击整数的缺点是每个算术运算1)都经过额外的指针间接,2)需要为结果分配一个对象。这通常非常慢

Java虚拟机将此表示用于所有类类型的变量和字段。这就是为什么int很快而且Integer很慢(除了优化等等)。

2:两个字

另一种可能的表示是使用两个词来表示每个值。第一个是类型标记,第二个是立即值(在整数,布尔值,字符等类型的情况下)或指针(在字符串,对象,数组等的情况下)。

这消除了与装箱整数等相关的分配和内存间接问题,但它使值表示的两倍大,这是浪费。

3:带标记位的一个字

第三种表示通过将类型标记和值压缩为单个单词来“优化”第二种表示。如果所有对象都是32位对齐的,则每个有效指针都以2个零位结束。 (或者对于64位对齐等为3)这些位可用于区分极少数基本类型。例如,这是一个标记系统:

  1. xxxxxx00表示整数值xxxxxx(符号扩展)。此表示中的整数称为“fixnums”。
  2. vvvvvv01表示vvvvvv被解释为另一种小值(如布尔值,“null”,字符等)
  3. pppppp10表示地址pppppp00处的对象(对象以更详细的类型标题开头)
  4. 与上面的表示2类似,此表示方案也避免装箱(大多数)小数据,但它避免膨胀,因为值仍然由单个单词表示。它需要与垃圾收集器进行一定程度的合作(识别并遵循指针),但2也是如此。

    对于像Scheme这样的语言,它具有无限大小的整数以及其他类型的数字,如“flonums”(浮点数)和“ratnums”(精确有理数或分数),算术运算如{ {1}}编译如下:

    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都是固定项,那么计算就会在线上发生并且速度很快。

    这种表示是快速而紧凑的,尽管操作(原始算术,对象字段提取等)在检查和补偿标记位时变得更加复杂。这种方法的一个缺点是,如果您使用典型的类型,安全语言(如Java,C#,ML等)编写解释器/ VM,通常无法使用它。类型系统不会让您将整数块转换为指针。你可以在C中做到这一点,这是不安全的。

    这种表示思想的另一个变体是“NaN编码”:大约有2 ^ 51个位模式,这意味着“不是数字”作为IEEE双精度浮点数。为什么不将有效的浮点数表示为自身并将其他值打包到NaN空间?

    以下是一些参考资料:

答案 1 :(得分:0)

动态语言中的变量通常是对类实例或对象的引用(对于某些语言,有时会以int的数据类型构建)。

他们可以在"生命周期期间接收对不同对象(或类实例)的引用。 (存在垃圾收集的地方),因此它们的类型是由对象的类型(是intstring还是用户定义的Person?)得出的。

当确定对象的类型时,不同的语言会以不同的方式实现它。

例如,Python使用元类来确定类的类型,并在确定类型的对象时使用该信息。

Javascript使用除正常属性说明符(类似于元类)以外的对象,以及常规数据类型(integerfloatcharacter ...)。