当我们说一种语言是动态类型和静态类型时,这意味着什么?


当前回答

http://en.wikipedia.org/wiki/Type_system

Static typing A programming language is said to use static typing when type checking is performed during compile-time as opposed to run-time. In static typing, types are associated with variables not values. Statically typed languages include Ada, C, C++, C#, JADE, Java, Fortran, Haskell, ML, Pascal, Perl (with respect to distinguishing scalars, arrays, hashes and subroutines) and Scala. Static typing is a limited form of program verification (see type safety): accordingly, it allows many type errors to be caught early in the development cycle. Static type checkers evaluate only the type information that can be determined at compile time, but are able to verify that the checked conditions hold for all possible executions of the program, which eliminates the need to repeat type checks every time the program is executed. Program execution may also be made more efficient (i.e. faster or taking reduced memory) by omitting runtime type checks and enabling other optimizations. Because they evaluate type information during compilation, and therefore lack type information that is only available at run-time, static type checkers are conservative. They will reject some programs that may be well-behaved at run-time, but that cannot be statically determined to be well-typed. For example, even if an expression always evaluates to true at run-time, a program containing the code if <complex test> then 42 else <type error> will be rejected as ill-typed, because a static analysis cannot determine that the else branch won't be taken.[1] The conservative behaviour of static type checkers is advantageous when evaluates to false infrequently: A static type checker can detect type errors in rarely used code paths. Without static type checking, even code coverage tests with 100% code coverage may be unable to find such type errors. Code coverage tests may fail to detect such type errors because the combination of all places where values are created and all places where a certain value is used must be taken into account. The most widely used statically typed languages are not formally type safe. They have "loopholes" in the programming language specification enabling programmers to write code that circumvents the verification performed by a static type checker and so address a wider range of problems. For example, Java and most C-style languages have type punning, and Haskell has such features as unsafePerformIO: such operations may be unsafe at runtime, in that they can cause unwanted behaviour due to incorrect typing of values when the program runs. Dynamic typing A programming language is said to be dynamically typed, or just 'dynamic', when the majority of its type checking is performed at run-time as opposed to at compile-time. In dynamic typing, types are associated with values not variables. Dynamically typed languages include Groovy, JavaScript, Lisp, Lua, Objective-C, Perl (with respect to user-defined types but not built-in types), PHP, Prolog, Python, Ruby, Smalltalk and Tcl. Compared to static typing, dynamic typing can be more flexible (e.g. by allowing programs to generate types and functionality based on run-time data), though at the expense of fewer a priori guarantees. This is because a dynamically typed language accepts and attempts to execute some programs which may be ruled as invalid by a static type checker. Dynamic typing may result in runtime type errors—that is, at runtime, a value may have an unexpected type, and an operation nonsensical for that type is applied. This operation may occur long after the place where the programming mistake was made—that is, the place where the wrong type of data passed into a place it should not have. This makes the bug difficult to locate. Dynamically typed language systems, compared to their statically typed cousins, make fewer "compile-time" checks on the source code (but will check, for example, that the program is syntactically correct). Run-time checks can potentially be more sophisticated, since they can use dynamic information as well as any information that was present during compilation. On the other hand, runtime checks only assert that conditions hold in a particular execution of the program, and these checks are repeated for every execution of the program. Development in dynamically typed languages is often supported by programming practices such as unit testing. Testing is a key practice in professional software development, and is particularly important in dynamically typed languages. In practice, the testing done to ensure correct program operation can detect a much wider range of errors than static type-checking, but conversely cannot search as comprehensively for the errors that both testing and static type checking are able to detect. Testing can be incorporated into the software build cycle, in which case it can be thought of as a "compile-time" check, in that the program user will not have to manually run such tests. References Pierce, Benjamin (2002). Types and Programming Languages. MIT Press. ISBN 0-262-16209-1.

其他回答

静态类型语言(如c++、Java)和动态类型语言(如Python)的区别仅仅在于变量类型的执行。 静态类型语言对变量有静态数据类型,这里在编译期间检查数据类型,因此调试要简单得多……而动态类型语言则不这样做,它会检查执行程序的数据类型,因此调试有点困难。

此外,它们有一个非常小的区别,可以与强类型和弱类型语言相关联。强类型语言不允许将一种类型用作另一种类型。C和c++…而弱类型语言允许例如python

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

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

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

静态类型:

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等。

静态类型

在运行前检查类型,以便更早地捕获错误。

Examples = c++

动态类型

在执行期间检查类型。

示例= Python

甜蜜和简单的定义,但符合需求: 静态类型语言将类型绑定到整个作用域的变量(Seg: SCALA) 动态类型语言将类型绑定到变量引用的实际值。

静态类型语言(编译器解析方法调用和编译引用):

通常表现更好 更快的编译错误反馈 更好的IDE支持 不适合使用未定义的数据格式 当没有定义模型时,很难开始开发 更长的编译时间 在很多情况下需要编写更多的代码

动态类型语言(在运行程序中做出的决定):

较低的性能 更快的发展 有些bug可能只在稍后的运行时才会被检测到 适用于未定义的数据格式(元编程)