为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

慕慕0277861 2019-09-27 16:23:55

另外,一个暗示另一个吗?



查看完整描述

3 回答

?
HUWWW

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

静态类型的语言具有类型系统,该类型系统在实现时由实现(编译器或解释器)检查。类型检查拒绝某些程序,并且通过检查的程序通常带有一些保证。例如,编译器保证不对浮点数使用整数算术指令。

关于“强类型”的含义并没有真正的共识,尽管专业文献中使用最广泛的定义是使用“强类型”语言,但是程序员不可能解决类型系统所施加的限制。 。这个术语几乎总是用来描述静态类型的语言。

静态与动态

静态类型的反义词是“动态类型”,这意味着

  1. 运行时使用的值分为几种类型。

  2. 有关如何使用此类值有限制。

  3. 违反这些限制时,违反将被报告为(动态)类型错误。

例如,Lua是一种动态类型的语言,除其他外,还具有字符串类型,数字类型和布尔类型。在Lua中的每个值属于正好一个类型,但是这并不适用于所有动态类型语言的要求。在Lua中,允许串联两个字符串,但不允许串联一个字符串和一个布尔值。

强vs弱

“强类型”的反义词是“弱类型”,这意味着您可以在类型系统周围工作。众所周知,C是弱类型的,因为任何指针类型都可以通过强制转换直接转换为任何其他指针类型。Pascal原本是强类型的,但是设计的监督(未标记的变体记录)在类型系统中引入了漏洞,因此从技术上讲它是弱类型的。真正强类型语言的示例包括CLU,Standard ML和Haskell。实际上,标准ML已进行了多次修订,以消除在广泛部署该语言后发现的类型系统中的漏洞。

这到底是怎么回事?

总的来说,谈论“强”和“弱”并没有多大用处。类型系统是否存在漏洞与漏洞的确切数目和性质,在实践中出现的可能性以及利用漏洞的后果相比,并不那么重要。实际上,最好完全避免使用术语“强”和“弱”,因为

  • 业余爱好者经常将它们与“静态”和“动态”混为一谈。

  • 显然,某些人使用“弱类型”来谈论隐性转换的相对盛行或不存在。

  • 专业人士不能完全同意这些术语的含义。

  • 总体而言,您不太可能通知或启发您的听众。

可悲的事实是,在类型系统方面,“强”和“弱”在技术含义上并没有达成共识。 如果要讨论类型系统的相对强度,最好确切讨论提供了什么保证和不提供什么保证。例如,一个很好的问题是:“是否一定要通过调用该类型的构造函数之一来创建给定类型(或类)的每个值?” 在C语言中,答案是否定的。在CLU,F#和Haskell中,是的。对于C ++,我不确定,我想知道。

相比之下,静态类型化意味着在执行程序之前先检查程序,然后在启动程序之前将其拒绝。 动态类型化意味着执行过程中会检查的类型,而类型错误的操作可能会导致程序停止运行或在运行时发出错误信号。静态类型化的主要原因是要排除可能具有此类“动态类型错误”的程序。

一个暗示另一个吗?

从学徒的角度来看,不可以,因为“强”一词实际上没有任何意义。但实际上,人们几乎总是做以下两件事之一:

  • 他们(错误地)使用“强”和“弱”来表示“静态”和“动态”,在这种情况下,他们(错误地)正在交替使用“强类型”和“静态类型”。

  • 他们使用“强”和“弱”来比较静态类型系统的属性。很少有人听到有人谈论“强”或“弱”动态类型系统。除了FORTH并没有任何类型的类型系统,我无法想到可以颠覆类型系统的动态类型语言。根据定义,这些检查会进入执行引擎,并且每个操作在执行之前都会被检查是否健全。

无论哪种方式,如果一个人称一种语言为“强类型”,则该人很可能在谈论静态类型的语言。


查看完整回答
反对 回复 2019-09-27
?
慕森王

这经常被误解,所以让我澄清一下。


静态/动态打字

静态类型是类型绑定到变量的地方。在编译时检查类型。


动态类型是将类型绑定到值的地方。在运行时检查类型。


因此,以Java为例:


String s = "abcd";

s将“永远”成为一个String。在其生命周期中,它可能指向不同的Strings(因为s在Java中是引用)。它可能具有null值,但绝不会引用Integer或List。那是静态类型。


在PHP中:


$s = "abcd";          // $s is a string

$s = 123;             // $s is now an integer

$s = array(1, 2, 3);  // $s is now an array

$s = new DOMDocument; // $s is an instance of the DOMDocument class

那是动态打字。


强/弱键入

(编辑警报!)


强类型键入是一个没有广泛认同的含义的短语。大多数使用该术语来表示静态类型以外的内容的程序员都使用它来暗示编译器强制执行某种类型规则。例如,CLU具有强大的类型系统,该类型系统不允许客户端代码创建抽象类型的值,除非使用该类型提供的构造函数。C具有某种程度强的类型系统,但是由于程序始终可以将一种指针类型的值转换为另一种指针类型的值,因此它可以被“颠覆”到一定程度。因此,例如,在C中,您可以采用由返回的值malloc()并将其愉快地转换为FILE*,并且编译器不会尝试阻止您,甚至会警告您您在做任何狡猾的事情。


(最初的回答说了一个关于“在运行时不改变类型”的值的东西。我认识许多语言设计者和编译器作者,除了在类型方面可能进行了一些非常高级的研究外,我还不知道谈论值在运行时改变类型的人。系统,这被称为“强更新问题”。)


弱类型意味着编译器不会强制执行键入纪律,或者强制执行很容易被破坏。


该答案的原始内容将弱类型与隐式转换(有时也称为“隐式提升”)结合在一起。例如,在Java中:


String s = "abc" + 123; // "abc123";

这是代码中隐式提升的示例:123在与串联之前被隐式转换为字符串"abc"。可以说Java编译器将该代码重写为:


String s = "abc" + new Integer(123).toString();

考虑一个经典的PHP“开始于”问题:


if (strpos('abcdef', 'abc') == false) {

  // not found

}

这里的错误是strpos()返回匹配的索引,即0。将0强制转换为布尔值false,因此条件实际上为true。解决方案是使用===而不是==避免隐式转换。


此示例说明了隐式转换和动态类型的组合如何使程序员误入歧途。


比较一下Ruby:


val = "abc" + 123

这是一个运行时错误,因为在Ruby中,对象 123 并不仅仅因为它恰好传递给了+方法而隐式转换。在Ruby中,程序员必须明确转换:


val = "abc" + 123.to_s

比较PHP和Ruby是一个很好的例子。两种都是动态类型的语言,但是PHP具有很多隐式转换,而Ruby(如果您不熟悉它,也许会令人惊讶)没有。


静态/动态与强/弱

这里的重点是静态/动态轴独立于强/弱轴。人们可能会混淆它们,部分原因是强类型和弱类型的定义不仅不够明确,而且强者和弱者的确切含义尚无真正共识。因此,强/弱键入更多地是灰色而不是黑色或白色。


因此,回答您的问题:另一种最正确的说法是,静态类型是编译时类型安全,而强类型是运行时类型安全。


原因是静态类型语言中的变量具有必须声明的类型,并且可以在编译时进行检查。强类型语言具有在运行时具有类型的值,并且程序员很难在没有动态检查的情况下颠覆类型系统。


但重要的是要了解一种语言可以是静态/强,静态/弱,动态/强或动态/弱。


查看完整回答
反对 回复 2019-09-27
?
慕桂英546537

两者都是在两个不同轴上的极点:

  • 强类型与弱类型

  • 静态类型与动态类型

强类型表示,a不会自动从一种类型转换为另一种类型。弱类型则相反:Perl可以"123"在数字上下文中使用字符串,方法是将其自动转换为int 123。像python这样的强类型语言不会这样做。

静态类型意味着编译器会在编译时找出每个变量的类型。动态类型的语言只能在运行时确定变量的类型。


查看完整回答
反对 回复 2019-09-27

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信