静态/dynamic与强/弱

我看到这些术语在编程中遍地开花,我对它们的含义有一个模糊的概念。 一个search显示我这样的东西实际上已经被问到了所有的堆栈溢出。 据我所知静态/dynamic键入语言与强/弱打字有微妙的不同,但是这种差异是没有办法。 不同的来源似乎使用不同的含义,甚至交替使用这些术语。 我找不到可以谈论这两者的地方,并且实际上阐明了这个区别。 如果有人能在这里为我和世界其他地方明确阐述这一点,那将是一件好事。

  • 静态/dynamictypes是指何时获取types信息(在编译时或运行时)

  • 强/弱types是关于如何区分types是否严格 (例如,语言是否试图从string到数字进行隐式转换)。

请参阅维基页面了解更多详细信息。

你已经发现了一个业余爱好者用来谈论编程语言的术语。 不要使用“强”和“弱”这两个词 ,因为他们没有普遍的技术含义。 相比之下, 静态types意味着程序在被执行之前被检查 ,并且程序在开始之前可能被拒绝。 dynamictypes意味着执行期间检查的types,而types错误的操作可能会导致程序在运行时暂停或发出错误信号 。 静态types的主要原因是排除可能有这种“dynamictypes错误”的程序。

强types一般意味着types系统没有漏洞 ,而弱types意味着types系统可以被颠覆(使任何保证无效)。 这些术语经常被错误地用来表示静态和dynamic的input。 为了看清楚它们之间的区别,想一想C语言是在编译时进行types检查的(静态types),但是有很多漏洞; 你几乎可以将任何types的值转换为相同大小的另一种types—特别是可以自由地转换指针types。 帕斯卡尔是一种意欲强烈打字的语言,但着名的却有一个无法预料的漏洞:一个没有标签的变种logging。

强types语言的实现往往会随着时间的推移而产生漏洞,通常这样一来,运行时系统的一部分就可以用高级语言来实现。 例如,Objective Caml有一个名为Obj.magic的函数,它具有简单地返回它的参数的运行时间效果,但是在编译时它将任何types的值转换成任何其他types的值。 我最喜欢的例子是Modula-3,他们的devise者称他们的types铸造构造LOOPHOLE

话虽如此,你不能指望任何两个人用完全相同的方式使用“强”和“弱”两个字。 所以避免它们。

简单地说就是:在静态types语言中 ,types是静态的 ,意思是一旦你设置了一个variablestypes,你就不能改变它。 这是因为键入与variables而不是它所指的值相关联。

例如在Java中:

 String str = "Hello"; //statically typed as string str = 5; //would throw an error since java is statically typed 

而在dynamictypes语言中 ,types是dynamic的 ,这意味着在将variables设置为types之后,可以对其进行更改。 这是因为打字与价值而不是variables相关联。

例如在Python中:

 str = "Hello" # it is a string str = 5 # now it is an integer; perfectly OK 

另一方面,语言中的强/弱types与隐式types转换有关(部分来自@Dario的回答):

例如在Python中:

 str = 5 + "hello" # would throw an error since it does not want to cast one type to the other implicitly. 

而在PHP中:

 $str = 5 + "hello"; // equals 5 because "hello" is implicitly casted to 0 // PHP is weakly typed, thus is a very forgiving language. 

静态types允许在编译时检查types的正确性。 静态types语言通常被编译,dynamictypes语言被解释。 因此,dynamictypes语言可以在运行时检查input。

弱types意味着对象的types可以根据上下文而改变。 例如,在弱types语言中,如果向其中添加另一个数字,则string“123”可被视为数字123。 弱打字的语言示例是bash,awk和PHP。

另一种弱types的语言是C,在内存地址的数据可以被视为一个不同types的铸造。

在一个强types语言中,一个对象的types不会改变 – 一个int总是一个int,并且试图把它作为一个string使用会导致错误。 Java和Python都是强types的。

dynamic和静态types之间的区别在于types规则被强制执行时。 在静态types语言中,每个variables和参数的types必须在源代码中声明,并在编译时执行。 在dynamictypes语言中,只有在运行时才使用types。 所以Java是静态types的,Python是dynamictypes的。

但是有时候,边界可能会有些模糊。 例如,虽然Java是静态types的,但是每次使用reflection或转换(例如使用对象的容器时),都会将types检查推迟到运行时。

同样,大多数强types的语言仍然会自动在整数和浮点数之间进行转换(以及某些语言的abitrary precision BigInts)。

今天研究这个问题,我遇到了这个伟大的文章http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html它清理了很多对我来说,我认为这可能会增加上面的一些伟大的答案。;

强和弱键入:

最常见的方式types系统可能被分类为“强”或“弱”。 这是不幸的,因为这些话几乎没有意义。 在一定程度上,可以比较两种语言types非常相似的types,并指定一个具有更强的两个系统。 除此之外,这些话毫无意义。

静态和dynamictypes

这几乎是唯一具有真正意义的types系统的通用分类。 事实上,它的意义往往是低估[…]dynamic和静态types系统是两个完全不同的东西,其目标发生部分重叠。

静态types系统是编译器检查源代码并将标签(称为“types”)分配给语法片段,然后使用它们来推断关于程序行为的一些机制的机制。 dynamictypes系统是编译器生成代码以跟踪程序使用的数据种类(巧合地,也称为“types”)的机制。 在这两个系统的每一个中使用“types”这个词,当然并不是真的完全是巧合; 但最好理解为具有一种弱的历史意义。 试图find一个世界观,其中“types”在两个系统中都是相同的东西,这会造成很大的混淆。 它不。

显式/隐式types:

当使用这些术语时,它们是指编译器对程序的静态types部分进行推理的程度。 所有的编程语言都有一些关于types的推理。 有些人比别人多。 ML和Haskell具有隐式types,因此不需要(或者很less,取决于使用的语言和扩展)types声明。 Java和Ada有非常明确的types,一个是不断地声明事物的types。 以上都有(比较相对于C和C ++)强静态types系统。

我认为其他同事尤其擅长。 解释了静态和dynamictypes之间的区别。 但就打字强弱而言,应该说是有不同的理解/看法。

这里有两个例子:

  • 有人说,Haskell是强types的,因为你不允许任何types的转换。

  • 其他人(比如达里奥的观点)认为,一种允许从string到数字的转换的语言是弱types的,但即使是其他人称之为鸭子打字。

这两个陈述都强调不是types体系的相反极端,而是完全不同的方面。 因此,我同意拉姆齐先生的观点,不要用“强”和“弱”来区分types体系。

静态v / sdynamictypes语言

  • 静态types语言是在编译时进行types检查的语言,所以这也意味着在静态types的语言中,每个variables都有一个types,并且在过程中不会改变。 相比之下, dynamictypes的lanaguges是那些在运行时进行types检查的types,并且在编译时没有types检查,所以这也意味着在dynamictypes语言中可能有也可能不是一个与variables相关联的types ,如果一个types是相关联的,那么它可能是一个genericstypes,如JS中的“var”,对于string和数字都有效。
    • “dynamictypes检查语言的实现通常将每个运行时对象与包含types信息的types标记(即对types的引用)相关联。 这个运行时types信息(RTTI)也可以用来实现dynamic调度,后期绑定,下拉投射,reflection和类似的function。
  • 即使语言是静态types,仍然可以有一些dynamictypes的function,这基本上意味着某种types的运行时检查。 这在铸造types中很有用。
    • “许多有用的和常见的编程语言特性不能静态检查,比如下拉式。 因此,许多语言将同时具有静态和dynamictypes检查; 静态types检查器validation它可以做什么,dynamic检查validation其余的。“
  • “有些语言允许编写不是types安全的代码。 例如,在C语言中,程序员可以在任何两个具有相同大小的types之间自由地赋值。“
  • “静态”式的优势是:
    • 由于大多数types检查是在编译时完成的,所以解释器或运行时可以全速运行,而不用担心types。
    • 它会导致运行时exception或与types相关的错误的数量减less,因为大多数types检查是在编译时完成的。
  • “dynamic”types的lanaguges的优点是:
    • 因为开发人员不需要了解types系统,所以开发人员可以松散地创buildvariables并运行它,这样可以帮助开发速度非常快的原型。
  • 静态和dynamictypes的lanaguges列表
    • 静态:
      • Java的
      • C(C是一种静态types的语言,但与Java相比,强度较低,因为它允许更多的隐式转换)
      • C ++
      • C#
    • dynamic:
      • PERL
      • PHP
      • python
      • JavaScript的
      • ruby
  • types检查是一个重要的安全function。 假设没有types检查,并且一个方法接受一个types为“BankAccount”的对象,该对象具有一个名为“creditAccount(BankAccountDetails)”的方法,现在在运行时如果没有types检查,那么我可以传递一个我自己的对象类,它有相同的方法“creditAccount(BankAccountDetails)”,它会得到执行,考虑到我们正在谈论面向对象的语言,因为OOP支持“多态”,这里我们正在讨论的只不过是“多态”。 因此,基本上面向对象的语言(基本上意味着它支持“多态性”)没有强大的types检查可能导致安全问题。

强烈的v / s弱types的lanaguges

  • 强types的lanaguges是那些在精度损失的情况下不允许隐式转换的types。 例如,在Java中,你可以投一个“int long”,因为没有精度的损失,但是你不能“隐式地”把一个“long转换为int”,因为会导致精度的损失。 相反,在弱types的lanaguges中,即使有精度损失,也允许隐式转换。
  • 我认为dynamictypes语言也可以是强types语言,如果“在运行时”它不允许隐含的转换,其中有精度损失。

好的进一步阅读

  • Type_system
  • Strong_and_weak_typing
  • 类别:Statically_typed_programming_languages
  • 类别:Dynamically_typed_programming_languages

静态types语言通常要求你声明variables的types,然后在编译时检查这些types以减less错误。 “静态types”中的“静态”一词是指“静态代码分析”,即在执行代码之前检查代码的过程。 尽pipe静态types语言可以从expression式的右边或实际参数中推断出variables的types,实际上大多数静态types语言要求显式声明variablestypes。

dynamictypes的语言通常不需要variables声明来获得types,而且它们根据计算得出的types来推断variablestypes,这是由于每个赋值语句的右边或者函数调用的实际参数。 由于variables在其生命周期中可以被赋予多个赋值,因此它的types可以随时间变化,这就是为什么它被称为“dynamictypes”的原因。 另外,运行时环境需要跟踪每个variables的当前types,因此types被绑定到值而不是variables声明。 这可以被认为是运行时间types信息(RTTI)系统。

静态和dynamictypes语言的元素可以结合使用。 例如,C#支持静态和dynamictypes的variables,面向对象的语言通常支持向下转换types层次结构。 静态types语言通常提供各种绕过types检查的方法,例如通过使用投射,reflection和dynamic调用。

强与弱打字是指语言尝试防止由于使用variables而出现错误的连续体,就好像它是另一种types的variables一样。 例如,C和Java都是静态types语言,但是Java使用比C更强的types检查。下面的C代码很乐意编译和运行,并且会在运行时将一个随机值放入variablesb中,这很可能导致BUG:

 char *a = "123"; int b = (int)a; 

等价的Java代码将产生一个编译错误,这通常是最好的:

 String a = "123" int b = (int)a;