当我们说一种语言是动态类型和静态类型时,这意味着什么?
当前回答
静态类型: Java和Scala等语言是静态类型的。
在代码中使用变量之前,必须对变量进行定义和初始化。
对于exp . int x;X = 10;
System.out.println (x);
动态类型: Perl是一种动态类型语言。
变量在代码中使用之前不需要初始化。
y = 10;在后面的代码中使用这个变量
其他回答
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、c++、Java。
动态类型:在运行时执行的类型检查。
动态类型语言的真正含义是:
不需要指定变量的类型 同一个变量可以引用不同类型的对象
Python、Ruby都是动态类型语言的例子。
*一些对象可以通过类型转换分配给不同类型的变量(在C和c++等语言中非常常见的做法)
下面是一个对比Python(动态类型)和Go(静态类型)如何处理类型错误的例子:
def silly(a):
if a > 0:
print 'Hi'
else:
print 5 + '3'
Python在运行时执行类型检查,因此:
silly(2)
运行完全正常,并产生预期的输出Hi。只有当有问题的行被击中时才会引发错误:
silly(-1)
生产
不支持'int'和'str'的操作数类型
因为相关的行已经被执行了。
另一方面,Go在编译时进行类型检查:
package main
import ("fmt"
)
func silly(a int) {
if (a > 0) {
fmt.Println("Hi")
} else {
fmt.Println("3" + 5)
}
}
func main() {
silly(2)
}
上述文件将无法编译,并出现以下错误:
无效的操作:"3" + 5(不匹配的类型字符串和int)
编译vs.解释
“当源代码被翻译时”
源代码:原始代码(通常由人输入计算机) 翻译:将源代码转换为计算机可以阅读的内容(即机器代码) 运行时间:程序执行命令的时间(编译后,如果编译) 编译语言:在运行时之前翻译的代码 解释语言:在执行过程中动态翻译的代码
打字
当类型被检查时
5 + '3'是强类型语言(如Go和Python)中类型错误的一个例子,因为它们不允许“类型强制”——>值在某些上下文中改变类型的能力,例如合并两种类型。弱类型语言,如JavaScript,不会抛出类型错误(结果为'53')。
静态:运行前检查的类型 动态:在执行期间动态检查类型
“静态和编译”和“动态和解释”的定义非常相似……但是记住,当类型被检查时。“当源代码被翻译时”。
无论语言是编译的还是解释的,你都会得到相同的类型错误!你需要从概念上区分这些术语。
Python示例
动态的,解释
def silly(a):
if a > 0:
print 'Hi'
else:
print 5 + '3'
silly(2)
因为Python是解释性的和动态类型的,所以它只翻译和类型检查它所执行的代码。else块永远不会执行,所以5 + '3'甚至永远不会被查看!
如果它是静态类型的呢?
甚至在代码运行之前就会抛出类型错误。即使它是解释的,它仍然在运行时之前执行类型检查。
如果它是编译的呢?
else块将在运行时之前被转换/查看,但因为它是动态类型的,所以不会抛出错误!动态类型语言直到执行才检查类型,而这一行永远不会执行。
去的例子
静态的,编译
package main
import ("fmt"
)
func silly(a int) {
if (a > 0) {
fmt.Println("Hi")
} else {
fmt.Println("3" + 5)
}
}
func main() {
silly(2)
}
类型在运行前检查(静态),类型错误立即被捕获!如果是解释类型,则在运行时之前仍将检查类型,结果相同。如果它是动态的,即使在编译期间查看代码,它也不会抛出任何错误。
性能
如果编译语言是静态类型(而不是动态类型),那么它在运行时的性能会更好;类型知识允许机器代码优化。
静态类型语言本质上在运行时具有更好的性能,因为在执行时不需要动态地检查类型(它在运行前检查)。
类似地,编译语言在运行时速度更快,因为代码已经被翻译,而不需要动态地“解释”/翻译。
注意,编译语言和静态类型语言在分别进行翻译和类型检查之前都会有一个延迟。
更多的差异
静态类型在早期捕获错误,而不是在执行期间发现错误(对长程序特别有用)。它更“严格”,因为它不允许程序中的任何地方出现类型错误,并且经常防止变量改变类型,这进一步防止了意外错误。
num = 2
num = '3' // ERROR
动态类型更灵活,这一点受到一些人的赞赏。它通常允许变量更改类型,这可能导致意外错误。