静态/动态类型和强/弱类型之间的区别是什么?


当前回答

今天在研究这个主题时,我看到了这篇很棒的文章http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html,它为我理清了很多事情,我认为它可能会为上面的一些伟大的答案补充一些东西。

强和弱打字:

可能类型系统最常见的分类方法是“强” 或“弱”。这是不幸的,因为这些话几乎没有 完全没有意义。在有限的范围内,比较两者是可能的 具有非常相似类型系统的语言,并指定其中一个为具有 这两个系统中较强的一个。除此之外,这些话毫无意义 在所有。

静态和动态类型

This is very nearly the only common classification of type systems that has real meaning. As a matter of fact, it's significance is frequently under-estimated [...] Dynamic and static type systems are two completely different things, whose goals happen to partially overlap. A static type system is a mechanism by which a compiler examines source code and assigns labels (called "types") to pieces of the syntax, and then uses them to infer something about the program's behavior. A dynamic type system is a mechanism by which a compiler generates code to keep track of the sort of data (coincidentally, also called its "type") used by the program. The use of the same word "type" in each of these two systems is, of course, not really entirely coincidental; yet it is best understood as having a sort of weak historical significance. Great confusion results from trying to find a world view in which "type" really means the same thing in both systems. It doesn't.

显式或隐式类型:

When these terms are used, they refer to the extent to which a compiler will reason about the static types of parts of a program. All programming languages have some form of reasoning about types. Some have more than others. ML and Haskell have implicit types, in that no (or very few, depending on the language and extensions in use) type declarations are needed. Java and Ada have very explicit types, and one is constantly declaring the types of things. All of the above have (relatively, compared to C and C++, for example) strong static type systems.

其他回答

静态/动态类型是关于获取类型信息的时间(在编译时或在运行时) 强/弱类型是关于如何严格区分类型(例如,语言是否试图进行从字符串到数字的隐式转换)。

更多详细信息请参见维基页面。

弱类型意味着对象的类型可以根据上下文而改变。例如,在弱类型语言中,字符串“123”如果添加另一个数字,可能会被视为数字123。具有弱类型的语言示例有bash、awk和PHP。

另一种弱类型语言是C语言,其中内存地址上的数据可以通过强制转换被视为不同的类型。

在强类型语言中,对象的类型不会改变——int始终是int,试图将其用作字符串将导致错误。Java和Python都是强类型的。

动态类型和静态类型之间的区别在于类型规则何时被强制执行。在静态类型语言中,每个变量和参数的类型都必须在源代码中声明,并在编译时强制执行。在动态类型语言中,类型只在运行时使用时进行检查。Java是静态类型,Python是动态类型。

然而,界限有时会有点模糊。例如,尽管Java是静态类型的,但每次你使用反射或强制转换(例如,当使用对象容器时),你都将类型检查推迟到运行时。

类似地,大多数强类型语言仍然会在整数和浮点数之间自动转换(在某些语言中是任意精确的bigint)。

Statically typed languages generally require you to declare the types of variables, which is then checked at compile time to reduce errors. The word "static" in "statically typed" refers to "static code analysis", which is the process of examining the code prior to executing it. Although it is possible for a statically typed language to infer the type of the variable from the right hand side of an expression or actual parameters, in practice most statically typed languages require variable types to be explicitly declared.

Dynamically typed languages generally do not require variable declarations to have types, and they infer variable types based on the type calculated as a result of evaluating the right hand side of every assignment statement or the actual parameters to a function call. Since the variable can be given multiple assignments over its lifetime, its type can change over time and this is why it is called "dynamically typed". Also, the runtime environment needs to keep track of the current type for each variable, so the type is bound to the value rather than with the variable declaration. This can be considered a runtime type information (RTTI) system.

静态类型语言和动态类型语言的元素可以组合。例如,c#既支持静态类型变量,也支持动态类型变量,而面向对象语言通常支持类型层次结构的向下转换。静态类型语言通常提供各种绕过类型检查的方法,例如使用强制转换、反射和动态调用。

强类型和弱类型指的是语言在多大程度上试图防止由于使用变量而导致的错误,就好像它是一种类型,而实际上它是另一种类型。例如,C和Java都是静态类型语言,但是Java使用了比C强大得多的类型检查。下面的C代码很容易编译和运行,并会在运行时将一个随机值放入变量b中,很可能会导致错误:

char *a = "123";
int b = (int)a;

等效的Java代码将产生一个编译错误,这通常是可取的:

String a = "123"
int b = (int)a;

从Scott的《编程语言语用学》第3版291页,我们有

Type checking is the process of ensuring that a program obeys the language’s type compatibility rules. A violation of the rules is known as a type clash. A language is said to be strongly typed if it prohibits, in a way that the language implementation can enforce, the application of any operation to any object that is not intended to support that operation. A language is said to be statically typed if it is strongly typed and type checking can be performed at compile time. In the strictest sense of the term, few languages are statically typed. In practice, the termis often applied to languages in which most type checking can be performed at compile time, and the rest can be performed at run time. A few examples: Ada is strongly typed, and for the most part statically typed (certain type constraints must be checked at run time). A Pascal implementation can also do most of its type checking at compile time, though the language is not quite strongly typed: untagged variant records (to be discussed in Section 7.3.4) are its only loophole. C89 is significantly more strongly typed than its predecessor dialects, but still significantly less strongly typed than Pascal. Its loopholes include unions, subroutineswith variable numbers of parameters, and the interoperability of pointers and arrays (to be discussed in Section 7.7.1). Implementations of C rarely check anything at run time. Dynamic (run-time) type checking is a form of late binding, and tends to be found in languages that delay other issues until run time as well. Lisp and Smalltalk are dynamically (though strongly) typed. Most scripting languages are also dynamically typed; some (e.g., Python and Ruby) are strongly typed. Languages with dynamic scoping are generally dynamically typed (or not typed at all): if the compiler can’t identify the object to which a name refers, it usually can’t determine the type of the object either.

因此,简单来说,静态/动态类型指的是发生类型检查的时间:静态类型是编译时间,动态语言是运行时间。类似地,强/弱类型指的是一种语言在强制执行其类型系统时的积极程度。

我试着把斯科特的描述翻译成一个漂亮的图表,我贴在下面。

今天在研究这个主题时,我看到了这篇很棒的文章http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html,它为我理清了很多事情,我认为它可能会为上面的一些伟大的答案补充一些东西。

强和弱打字:

可能类型系统最常见的分类方法是“强” 或“弱”。这是不幸的,因为这些话几乎没有 完全没有意义。在有限的范围内,比较两者是可能的 具有非常相似类型系统的语言,并指定其中一个为具有 这两个系统中较强的一个。除此之外,这些话毫无意义 在所有。

静态和动态类型

This is very nearly the only common classification of type systems that has real meaning. As a matter of fact, it's significance is frequently under-estimated [...] Dynamic and static type systems are two completely different things, whose goals happen to partially overlap. A static type system is a mechanism by which a compiler examines source code and assigns labels (called "types") to pieces of the syntax, and then uses them to infer something about the program's behavior. A dynamic type system is a mechanism by which a compiler generates code to keep track of the sort of data (coincidentally, also called its "type") used by the program. The use of the same word "type" in each of these two systems is, of course, not really entirely coincidental; yet it is best understood as having a sort of weak historical significance. Great confusion results from trying to find a world view in which "type" really means the same thing in both systems. It doesn't.

显式或隐式类型:

When these terms are used, they refer to the extent to which a compiler will reason about the static types of parts of a program. All programming languages have some form of reasoning about types. Some have more than others. ML and Haskell have implicit types, in that no (or very few, depending on the language and extensions in use) type declarations are needed. Java and Ada have very explicit types, and one is constantly declaring the types of things. All of the above have (relatively, compared to C and C++, for example) strong static type systems.