这两个定义哪一个是正确的?
- 静态类型- 在编译时检查类型匹配(因此只能应用于编译语言)
- 动态类型- 在运行时检查类型匹配,或者根本不检查。(这个术语可以应用于编译或解释语言)
- 静态类型- 类型被分配给变量,所以我会说'x is of type int'。
- 动态类型- 类型被分配给值(如果有的话),所以我会说'x 持有一个 int'
根据这个定义,静态或动态类型不依赖于编译或解释语言。
哪个是正确的,或者两者都不完全正确?
这两个定义哪一个是正确的?
根据这个定义,静态或动态类型不依赖于编译或解释语言。
哪个是正确的,或者两者都不完全正确?
哪个是正确的,或者两者都不完全正确?
第一对定义更接近但并不完全正确。
静态类型- 在编译时检查类型匹配(因此只能应用于编译语言)
这很棘手。我认为如果一种语言被解释但在执行开始之前进行了类型检查,那么它仍然是静态类型的。OCaml REPL 几乎就是一个例子,除了它在技术上将源代码编译(和类型检查)成自己的字节码,然后解释字节码。
动态类型- 在运行时检查类型匹配,或者根本不检查。
相当:
动态类型- 类型检查在运行时完成。
Untyped - 未进行类型检查。
静态类型- 类型被分配给变量,所以我会说“x 是 int 类型”。
动态类型- 类型被分配给值(如果有的话),所以我会说'x 持有一个 int'
变量无关紧要。尽管您只能在许多静态类型语言的源代码中的变量和函数定义中显式地看到类型,但所有子表达式也具有静态类型。例如,"foo" + 3
通常是静态类型错误,因为您不能将字符串添加到 int 但不涉及变量。
查看静态一词的一种有用方法是:静态属性是在所有可能的输入上为程序的所有可能执行所保留的属性。然后,您可以查看任何给定的语言或类型系统,并考虑它可以验证哪些静态属性,例如:
JavaScript:没有段错误/内存错误
Java/C#/F#:如果编译的程序和变量的类型为 T,则该变量仅保存此类型的值 - 在所有执行中。但是,可悲的是,引用类型也承认null
了一个价值——十亿美元的错误。
ML没有null
,使上述保证更强
Haskell 可以验证有关副作用的语句,例如“此程序不会在标准输出上打印任何内容”之类的属性
Coq 还验证终止 - “这个程序在所有输入上终止”
你想验证多少,这取决于口味和手头的问题。所有的魔法(验证)都是有代价的。
如果您以前从未见过 ML,请尝试一下。至少花 5 分钟关注 Yaron Minsky 的演讲。它可以改变你作为程序员的生活。
第二个在我看来是一个更好的定义,假设您不是在寻找关于事情为什么或如何运作的解释。
更好的做法是这样说
我喜欢后一个定义。考虑在 Java 或 C++ 等面向对象语言中从基类转换为派生类时的类型检查,这符合第二个定义而不是第一个定义。它是一种带有(可选)动态类型检查的编译语言。