静态/动态类型和强/弱类型之间的区别是什么?
当前回答
在编程中,数据类型是一种分类,它告诉变量将持有什么类型的值,以及可以对这些值进行哪些数学、关系和逻辑操作而不会出错。
在每种编程语言中,为了尽量减少出错的机会,类型检查都是在程序执行之前或执行过程中进行的。根据类型检查的时间,编程语言有两种类型:静态类型语言和动态类型语言。
也取决于是否发生隐式类型转换,编程语言有两种类型:强类型语言和弱类型语言。
静态类型:
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等。
其他回答
静态/动态类型是关于获取类型信息的时间(在编译时或在运行时) 强/弱类型是关于如何严格区分类型(例如,语言是否试图进行从字符串到数字的隐式转换)。
更多详细信息请参见维基页面。
摘自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;
我认为其他同事做得很好,特别是解释了静态类型和动态类型的区别。但就强类型和弱类型而言,应该说都有 不同的理解/观点。
这里有两个例子:
有人说Haskell是强类型的,因为不允许进行任何类型转换。 其他人(例如Dario的观点)说,允许有意地从字符串隐式转换为数字的语言是弱类型的,但甚至其他人称之为鸭子类型。
这两种说法强调的不是类型系统的两个极端,而是完全不同的方面。因此,我同意Ramsey先生的观点,不要用“强”和“弱”来区分类型系统。
简单地说:在静态类型语言中,类型是静态的,这意味着一旦将变量设置为类型,就不能更改它。这是因为类型是与变量而不是它所引用的值相关联的。
例如,在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.
静态类型允许在编译时检查类型正确性。静态类型的语言通常是编译的,动态类型的语言是解释的。因此,动态类型语言可以在运行时检查类型。