当我们说一种语言是动态类型和静态类型时,这意味着什么?
当前回答
静态类型语言
如果一个变量的类型在编译时已知,那么该语言就是静态类型的。对于某些语言,这意味着作为程序员的你必须指定每个变量的类型;其他语言(例如:Java, C, c++)提供了某种形式的类型推断,类型系统推断变量类型的能力(例如:OCaml, Haskell, Scala, Kotlin)。
这样做的主要优点是编译器可以完成所有类型的检查,因此在非常早期的阶段就可以捕捉到许多微不足道的错误。
例如:C, c++, Java, Rust, Go, Scala
动态类型语言
如果一种语言的类型与运行时值相关联,而不是命名变量/字段等,则该语言是动态类型的。这意味着作为程序员,您可以编写得更快一些,因为您不必每次都指定类型(除非使用带有类型推断的静态类型语言)。
例如:Perl, Ruby, Python, PHP, JavaScript, Erlang
大多数脚本语言都有这个特性,因为没有编译器来进行静态类型检查,但您可能会发现自己在搜索由于解释器错误解释变量类型而导致的错误。幸运的是,脚本往往很小,所以bug没有那么多藏身之处。
大多数动态类型语言允许您提供类型信息,但不要求提供类型信息。目前正在开发的一种语言Rascal采用了一种混合方法,允许函数内的动态类型,但对函数签名强制执行静态类型。
其他回答
静态类型语言(编译器解析方法调用和编译引用):
通常表现更好 更快的编译错误反馈 更好的IDE支持 不适合使用未定义的数据格式 当没有定义模型时,很难开始开发 更长的编译时间 在很多情况下需要编写更多的代码
动态类型语言(在运行程序中做出的决定):
较低的性能 更快的发展 有些bug可能只在稍后的运行时才会被检测到 适用于未定义的数据格式(元编程)
甜蜜和简单的定义,但符合需求: 静态类型语言将类型绑定到整个作用域的变量(Seg: SCALA) 动态类型语言将类型绑定到变量引用的实际值。
静态类型语言:每个变量和表达式在编译时就已经知道了。
(int;A在运行时只能接受整型值)
例如:C, c++, Java
动态类型语言:变量可以在运行时接收不同的值,它们的类型在运行时定义。
(var;A可以在运行时取任何类型的值)
例如:Ruby, Python。
静态类型语言在编译时进行类型检查,并且类型不能更改。(不要用类型转换注释,会创建一个新的变量/引用)。
动态类型语言在运行时进行类型检查,变量的类型可以在运行时更改。
简单地说:在静态类型语言中,变量的类型是静态的,这意味着一旦将变量设置为类型,就不能更改它。这是因为类型是与变量而不是它所引用的值相关联的。
例如,在Java中:
String str = "Hello"; // variable str statically typed as string
str = 5; // would throw an error since str is
// supposed to be a string only
另一方面:在动态类型语言中,变量的类型是动态的,这意味着在你将变量设置为类型后,你可以更改它。这是因为输入与它假设的值相关,而不是变量本身。
例如,在Python中:
some_str = "Hello" # variable some_str is linked to a string value
some_str = 5 # now it is linked to an integer value; perfectly OK
因此,最好将动态类型语言中的变量视为指向类型值的泛型指针。
总而言之,类型描述(或应该描述)语言中的变量,而不是语言本身。恕我直言,它本可以更好地用作带有静态类型变量的语言,而不是带有动态类型变量的语言。
静态类型语言通常是编译语言,因此,编译器检查类型(这很有意义,对吧?因为类型不允许稍后在运行时更改)。
动态类型语言通常是解释型的,因此类型检查(如果有的话)发生在使用它们时的运行时。这当然会带来一些性能损失,也是动态语言(例如python、ruby、php)伸缩性不如类型化语言(java、c#等)的原因之一。从另一个角度来看,静态类型语言的启动成本更高:通常会让你编写更多、更难的代码。但这在以后是有回报的。
好在双方都在借鉴对方的特点。类型语言融合了更多的动态特性,例如c#中的泛型和动态库,而动态语言则包含了更多的类型检查,例如python中的类型注释,或PHP的HACK变体,这些通常不是语言的核心,可按需使用。
在技术选择方面,任何一方都没有内在的优势。这只是一个偏好的问题,你想要更多的控制或灵活性。只要为工作选择合适的工具,并确保在考虑转换之前检查相反的可用工具。