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


当前回答

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

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

其他回答

静态v/s动态类型语言

Statically typed languages are those in which type checking is done at the compile time, so this also means that in statically typed languages each variable has a type and it doesn’t change over the course. Now, in contrast, dynamically typed languages are those in which type checking is done at runtime, and there is no type checking at compile time, so this also means that in dynamically typed languages there may or may not be a type associated with a variables, and if a type is associated then it could be a generic type like “var” in JS which hold good for both a string and number. “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, down casting, reflection, and similar features.” Even if language is statically typed, still it could have some dynamically typed feature, which basically means that some sort of type checking at runtime as well. This is useful in casting of types. “A number of useful and common programming language features cannot be checked statically, such as down casting. Thus, many languages will have both static and dynamic type checking; the static type checker verifies what it can, and dynamic checks verify the rest.” “Some languages allow writing code that is not type-safe. For example, in C, programmers can freely cast a value between any two types that have the same size.” Advantage of “statically” typed languages are that: Since most of the type checking is done at compile time so interpreter or runtime can run at full speed, without worrying about the types. It leads to lesser number of runtime exception or errors related to type, because most of the type checking is done at compile time. Advantage of “dynamically” typed languages are that: They could help in extremely fast prototyping, since developer need not to understand the type system so dev can loosely create variables and run it, and this leads to very fast prototyping. List of statically and dynamically typed languages: Statically: Java C (C is a statically typed language but lesser “strongly” typed as compared to Java because it allows more implicit conversions) C++ C# Dynamically: PERL PHP Python JavaScript Ruby Type checking is an important security feature. Suppose, there is no type checking, and a method accepts an object of type “BankAccount” which has a method called as “creditAccount(BankAccountDetails)”, now at runtime if there is no type checking then I can pass an object of my own class which has same method “creditAccount(BankAccountDetails)” and it will get executed, considering we are talking about object oriented language because OOP supports “polymorphism” and here what we are discussing is nothing but “polymorphism”. So, basically an object oriented language (which basically means it supports “polymorphism”) which doesn’t have strong type checking can lead to security issues.

强v/s弱类型语言

Strongly typed languages are those in which implicit conversions are not allowed if there is loss of precision. For example, in Java, you can cast an “int to long” because there is no loss of precision but you cannot “implicitly” cast a “long to int” because there would be loss of precision. In contrast, in weakly typed languages, implicit conversions are allowed even if there is loss of precision. I think dynamically typed language can also be a strongly typed language if “at runtime” it doesn’t allow implicit conversions in which there is loss of precision.


很好的进一步阅读

Type_system Strong_and_weak_typing 类别:Statically_typed_programming_languages 类别:Dynamically_typed_programming_languages

我认为其他同事做得很好,特别是解释了静态类型和动态类型的区别。但就强类型和弱类型而言,应该说都有 不同的理解/观点。

这里有两个例子:

有人说Haskell是强类型的,因为不允许进行任何类型转换。 其他人(例如Dario的观点)说,允许有意地从字符串隐式转换为数字的语言是弱类型的,但甚至其他人称之为鸭子类型。

这两种说法强调的不是类型系统的两个极端,而是完全不同的方面。因此,我同意Ramsey先生的观点,不要用“强”和“弱”来区分类型系统。

摘自Addison Wesley,《面向对象的分析与应用设计》,第3期,第66页:

The concepts of strong and weak typing and static and dynamic typing are entirely different. Strong and weak typing refers to type consistency, whereas static and dynamic typing refers to the time when names are bound to types. Static typing (also known as static binding or early binding) means that the types of all variables and expressions are fixed at the time of compilation; dynamic typing (also known as late binding) means that the types of all variables and expressions are not known until runtime. A language may be both strongly and statically typed (Ada), strongly typed yet supportive of dynamic typing (C++, Java), or untyped yet supportive of dynamic typing (Smalltalk).

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.

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

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