协慌网

登录 贡献 社区

静态类型语言和动态类型语言有什么区别?

我听到很多新的编程语言都是动态输入的,但是当我们说一种语言是动态类型而非静态类型时,它实际意味着什么呢?

答案

静态类型语言

如果在编译时已知变量的类型,则静态键入语言。对于某些语言,这意味着您作为程序员必须指定每个变量的类型(例如:Java,C,C ++); 其他语言提供某种形式的类型推断 ,类型系统推断变量类型的能力(例如:OCaml,Haskell,Scala,Kotlin)

这里的主要优点是所有类型的检查都可以由编译器完成,因此很早就会发现许多琐碎的错误。

示例:C,C ++,Java,Rust,Go,Scala

动态类型语言

如果类型与运行时值相关联,则动态类型化语言,而不是命名变量 / 字段 / 等。这意味着您作为程序员可以更快地编写,因为您不必每次都指定类型(除非使用带有类型推断的静态类型语言)。

示例:Perl,Ruby,Python,PHP,JavaScript

大多数脚本语言都具有此功能,因为无论如何都没有编译器进行静态类型检查,但您可能会发现自己正在搜索由于解释器误解变量类型而导致的错误。幸运的是,脚本往往很小,所以 bug 没有那么多地方可以隐藏。

大多数动态类型语言都允许您提供类型信息,但不需要它。目前正在开发的一种语言Rascal采用混合方法,允许在函数内动态键入,但强制执行函数签名的静态类型。

静态类型编程语言在编译时进行类型检查(即验证和强制执行类型约束的过程),而不是运行时

动态类型编程语言在运行时进行类型检查,而不是编译时

下面是一个示例,对比 Python(动态类型)和 Go(静态类型)如何处理类型错误:

def silly(a):
    if a > 0:
        print 'Hi'
    else:
        print 5 + '3'

Python 在运行时进行类型检查,因此:

silly(2)

运行完美,并产生预期的输出Hi 。只有在遇到有问题的行时才会引发错误:

silly(-1)

产生

TypeError: unsupported operand type(s) for +: 'int' and 'str'

因为相关的线路实际上已经执行了。

另一方面,在编译时进行类型检查:

package main

import ("fmt"
)

func silly(a int) {
    if (a > 0) {
        fmt.Println("Hi")
    } else {
        fmt.Println("3" + 5)
    }
}

func main() {
    silly(2)
}

以上将无法编译,出现以下错误:

invalid operation: "3" + 5 (mismatched types string and int)