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


当前回答

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

其他回答

类型检查是验证和强制执行类型约束的过程。

静态类型编程语言在编译时进行类型检查。 例如:Java, C, c++。 动态类型编程语言在运行时进行类型检查。 例子: Perl, Ruby, Python, PHP, JavaScript。

编译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

动态类型更灵活,这一点受到一些人的赞赏。它通常允许变量更改类型,这可能导致意外错误。

静态类型: Java和Scala等语言是静态类型的。

在代码中使用变量之前,必须对变量进行定义和初始化。

对于exp . int x;X = 10;

System.out.println (x);

动态类型: Perl是一种动态类型语言。

变量在代码中使用之前不需要初始化。

y = 10;在后面的代码中使用这个变量

静态类型:在编译时执行的类型检查。

静态类型语言的真正含义是:

必须指定变量的类型 变量只能引用特定类型的对象* 值的类型检查将在编译时执行,任何类型检查都将在此时报告 将在编译时分配内存来存储该特定类型的值

静态类型语言的例子有C、c++、Java。

动态类型:在运行时执行的类型检查。

动态类型语言的真正含义是:

不需要指定变量的类型 同一个变量可以引用不同类型的对象

Python、Ruby都是动态类型语言的例子。


*一些对象可以通过类型转换分配给不同类型的变量(在C和c++等语言中非常常见的做法)

动态类型语言有助于快速构建算法概念原型,而不需要考虑需要使用什么变量类型(这在静态类型语言中是必要的)。