Skip to content

类型: 程序如何解释数据

类型是什么?直白讲就是人为给数据附加的一种说明。计算机中的数据由 1 0 来存储,而如何解释这些 1 0 组成的数据就是人为的约定,而这个约定就是类型的定义。

最初的的类型实际上就是为了解释计算机中的数值(整数、浮点数)。不过后来随着发展引入了日期时间、字符串等。甚至 C 语言还提供了结构体来允许用户定义类型。

知道面向对象的出现,类型有进一步进化到允许对数值施加何种操作等。因此目前的数据类型的含义包含一下几个重要方面:

  • 数据类型决定了如何描述内存中 1 0 这些数据
  • 数据类型决定了该字段的取值范围
  • 数据类型决定了允许执行那些操作

静态类型

所谓的静态类型就是处理器将变量名、保存数值的内存地址以及内存中存储的内容作为一个整体看待。这意味着我们在定义变量时就需要敲定变量能够存储的数据类型:

C
int x = 1;
int ret = x + 1024;

他的好处就是任何数据的类型在编译期间就是确定了,对于类型的操作也是确定了。因此就能够非常容易的检查到一些操作的错误。例如 int 没办法索引,如果不小心 ret[1] 编译器就会报错(甚至现在的 IDE 就直接指出了)。

范型

静态类型有一个问题在于如果我们需要的类型目前没办法确定,或者说存在多种情形。于是出现了模版或者叫做范型。他允许以类型作为参数来创建函数或类:

Java
// T 就是一个简单的变量名,他可以是任何合法的标识符
// 不过大家都喜欢用 T
class Person<T>{
  public Integer age;
  public String name;
  public T something;
}

public class GenericsTest{
  public static void main(string[] args){
    // 也就是以 Person 作为模版传入类型来创建一个新的类型
    // 这也是他也叫模版的原因(C++ 是这么叫的)
    Person<Integer> x = new Person<Integer>();
    x.something = 1;
    Person<String> y = new Person<String>();
    y.something = "hoge";
    System.out.println(x.something);  // -> 1
    System.out.println(y.something);  // -> hoge
  }
}

动态类型

如果只把类型的信息和数据看作一个整体,而不包含变量则就是动态类型。动态类型的一个特点就是变量不需要定义,或者说他的定义只是和作用域有关而和类型没有关系。现代的大多数脚本语言都采用了动态类型,例如 Python、JS、LISP 等。

我们从 Python 的动态类型实现来说明动态类型的性质。首先需要创建一个统一的数据类型,他能够表示所有的数据。在 Python 中这个数据类型是 PyObject:

PyObject

在 C 语言中 Python 的变量可以表示为 PyObject* x

在每次读取变量时,可以从表示值类型的位置处读取该变量的具体类型,对于整数、浮点数就从他的第三位获取值。而对于字符串他会从第三位获取大小然后从第六位之后读取该长度的值。

使用次数就是在内存管理中记录这个对象被多少变量引用,如果为 0 他会被垃圾回收。