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


当前回答

静态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

其他回答

静态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

今天在研究这个主题时,我看到了这篇很棒的文章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.

简单地说:在静态类型语言中,类型是静态的,这意味着一旦将变量设置为类型,就不能更改它。这是因为类型是与变量而不是它所引用的值相关联的。

例如,在Java中:

String str = "Hello";  //statically typed as string
str = 5;               //would throw an error since java is statically typed

而在动态类型语言中,类型是动态的,这意味着在将变量设置为类型之后,您可以更改它。这是因为类型与值而不是变量相关联。

例如,在Python中:

str = "Hello" # it is a string
str = 5       # now it is an integer; perfectly OK

另一方面,语言中的强/弱类型与隐式类型转换有关(部分取自@Dario的回答):

例如,在Python中:

str = 5 + "hello" 
# would throw an error since it does not want to cast one type to the other implicitly. 

而在PHP中:

$str = 5 + "hello"; // equals 5 because "hello" is implicitly casted to 0 
// PHP is weakly typed, thus is a very forgiving language.

静态类型允许在编译时检查类型正确性。静态类型的语言通常是编译的,动态类型的语言是解释的。因此,动态类型语言可以在运行时检查类型。

在编程中,数据类型是一种分类,它告诉变量将持有什么类型的值,以及可以对这些值进行哪些数学、关系和逻辑操作而不会出错。

在每种编程语言中,为了尽量减少出错的机会,类型检查都是在程序执行之前或执行过程中进行的。根据类型检查的时间,编程语言有两种类型:静态类型语言和动态类型语言。

也取决于是否发生隐式类型转换,编程语言有两种类型:强类型语言和弱类型语言。

静态类型:

Type checking is done at compile time In source code, at the time of variable declaration, data type of that variable must be explicitly specified. Because if data type is specified in source code then at compile time that source code will be converted to machine code and type checking can happen Here data type is associated with variable like, int count. And this association is static or fixed If we try to change data type of an already declared variable (int count) by assigning a value of other data type (int count = "Hello") into it, then we will get error If we try to change data type by redeclaring an already declared variable (int count) using other data type (boolean count) then also we will get error

int count;         /* count is int type, association between data type
                      and variable is static or fixed */

count = 10;        // no error 
count = 'Hello';   // error 
boolean count;     // error 

由于类型检查和类型错误检测是在编译时完成的,这就是为什么在运行时不需要进一步的类型检查。因此,程序变得更加优化,结果在更快的执行 如果我们想要更严格的代码,那么选择这种类型的语言是更好的选择 例如:Java, C, c++, Go, Swift等。

动态类型:

Type checking is done at runtime In source code, at the time of variable declaration, no need to explicitly specify data type of that variable. Because during type checking at runtime, the language system determines variable type from data type of the assigned value to that variable Here data type is associated with the value assigned to the variable like, var foo = 10, 10 is a Number so now foo is of Number data type. But this association is dynamic or flexible we can easily change data type of an already declared variable (var foo = 10), by assigning a value of other data type (foo = "Hi") into it, no error we can easily change data type of an already declared variable (var foo = 10), by redeclaring it using value of other data type (var foo = true), no error

var foo;            // without assigned value, variable holds undefined data type 

var foo = 10;       // foo is Number type now, association between data 
                    // type and value is dynamic / flexible 
foo = 'Hi';         // foo is String type now, no error 
var foo = true;     // foo is Boolean type now, no error 

由于类型检查和类型错误检测是在运行时完成的,这就是为什么程序变得不那么优化,导致执行速度变慢。尽管如果它们实现了JIT编译器,这些类型的语言的执行速度会更快 如果我们想要轻松地编写和执行代码,那么这种类型的语言是更好的选择,但在这里我们可能会得到运行时错误 例如:Python, JavaScript, PHP, Ruby等。

强类型:

严格维护数据类型相关规则和限制 从一种数据类型到另一种数据类型的转换必须显式进行,不能进行隐式类型转换

# in python, "5" cannot automatically get converted to 5
pybar = "5"

print(10 + pybar)     # error, no `+` operation between `int` and `str` 

类型检查可以在编译时或运行时进行。这意味着强类型语言既可以是静态类型的,也可以是动态类型的 例如:Python, Java, Ruby, c#等。

弱类型:

数据类型相关的规则和限制松散维护 从一种数据类型到另一种数据类型的转换可以隐式进行 如果我们在两个不匹配的数据类型的值之间执行一些操作,那么这种类型的语言可能不会抛出错误。相反,弱类型语言将应用它们自己的隐式类型转换规则,并将返回一些结果

jsbar = "5";

alert(10 + jsbar);  /* "105", no error as javascript implicitly coerces Number 10 
to String "10", so that it can be concatenated with other operand jsbar i.e. "5" */

类型检查可以在编译时或运行时进行。这意味着弱类型语言既可以是静态类型的,也可以是动态类型的 例如:JavaScript, C, c++, PHP等。

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

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