弱类型语言的优点(和缺点)是什么?
我是PHP的忠实粉丝,它显然是一种非常弱类型的语言。我意识到一些好处包括动态更改变量类型的一般独立性等。
我想知道的是缺点。你能从像C这样的强类型语言中得到什么,否则你无法从像PHP这样的弱类型语言中得到什么?同样对于类型设置(如double($variable)),人们可以争辩说,即使是弱类型语言也可以像强类型语言一样起作用。
所以,弱型。我没有包括哪些福利?更重要的是,有哪些缺点?
我是PHP的忠实粉丝,它显然是一种非常弱类型的语言。我意识到一些好处包括动态更改变量类型的一般独立性等。
我想知道的是缺点。你能从像C这样的强类型语言中得到什么,否则你无法从像PHP这样的弱类型语言中得到什么?同样对于类型设置(如double($variable)),人们可以争辩说,即使是弱类型语言也可以像强类型语言一样起作用。
所以,弱型。我没有包括哪些福利?更重要的是,有哪些缺点?
静态类型化的优点是,在编译时捕获了整个类别的错误,这些错误无法到达运行时。例如,如果您有一个静态类型的类或接口作为函数参数,那么您很不会意外地传入错误类型的对象(如果没有显式和不正确的强制转换)。
当然,这并不能阻止你传入正确类型的错误对象,或者一个接口的实现,你给了它正确的函数,但它们做了错误的事情。此外,如果你有100%的代码覆盖率,比如PHP / Python / etc的人,谁在乎你是在编译时还是在运行时捕获错误?
就我个人而言,我在静态打字的语言中度过了愉快的时光,在没有静态类型语言的语言中度过了愉快的时光。这很少是决定性的问题,因为我从来没有在两种语言之间做出选择,除了它们的打字方式之外,它们都是相同的,而且通常有更重要的事情需要担心。我确实发现,当我使用静态类型语言时,我故意“依靠编译器”,试图以这样的方式编写代码,如果它是错误的,它就不会编译。例如,您可以通过在一个地方进行更改来执行某些重构,然后修复导致的所有编译错误,重复直到干净编译。通过多次运行完整的测试套件来做同样的事情可能不是很实用。但是,对于IDE来说,在其他语言中自动执行相同的重构,或者让测试快速完成,这并不是闻所未闻的,所以这是一个方便的问题,而不是什么是可能的。
除了便利性和编码风格偏好之外,那些有合理关注的人是那些致力于代码正确性的正式证明的人。我的无知印象是,静态类型演绎可以完成显式静态类型所做的大部分(但不是全部)工作,并节省键盘上的大量磨损。因此,如果静态类型迫使人们以一种更容易证明的方式编写代码,那么从这个POV中可能会有一些东西。我说“如果”:我不知道,而且大多数人无论如何都不会证明他们的静态类型代码。
动态更改变量类型等
我认为这具有可疑的价值。做这样的事情总是那么诱人(Python/Django):
user = request.GET['username']
# do something with the string variable, "user"
user = get_object_or_404(User,user)
# do something with the User object variable, "user"
但实际上,是否应该将相同的名称用于函数中的不同事物?或。例如,“重用”,在静态类型语言中,对其他事物的整数变量也不大力鼓励。希望不必考虑简洁,描述性的变量名称,可能95%的时间不应该覆盖对明确代码的渴望......
顺便说一句,通常弱类型意味着隐式类型转换发生,而强类型意味着它们不会发生。根据这个定义,就算术类型而言,C是弱类型,所以我假设这不是你的意思。我认为人们普遍认为,完全强类型化与其说是帮助,不如说是一种麻烦,而“完全弱类型”(任何东西都可以转换为其他任何东西)在大多数语言中都是荒谬的。因此,问题在于在您的代码变得太难弄清楚之前,可以容忍多少种隐式转换以及哪些隐式转换。另请参阅C++,在决定是否实现转换运算符和非显式 one-arg 构造函数方面仍然存在困难。
一段时间以来,我一直在使用强类型(如Java)和弱类型(如JavaScript)语言。我发现弱类型语言的便利性非常适合小型应用程序。不幸的是,随着应用程序的大小增长,它变得无法管理。在你的脑海中有太多的东西需要跟踪,你必须开始越来越依赖于你的IDE和编译器,否则你的编码就会停止。那时,强类型语言开始变得更加有用 - 随着应用程序变得非常大。
在弱类型JavaScript中不断让我抓狂的两个例子是使用没有完全记录和重构的外部库。
外部库:在处理强类型语言时,库本身的代码提供自文档。当我创建一个 Person 类型的变量时,IDE 可以检查代码并告诉有一个 getFirstName()、getLastName() 和 getFullName()。在弱类型语言中,情况并非如此,因为变量可以是任何东西,具有任何类型的变量或函数,并且具有也可以是任何东西的函数参数(它们不是显式定义的)。因此,开发人员必须严重依赖文档,Web搜索,讨论论坛以及他们对过去使用情况的记忆。我发现在JavaScript中查找外部库可能需要几个小时,而使用Java时,我只需点击“.”键,它就会弹出所有选项并附加文档。当您遇到不是100%完整记录的库时,对于弱类型语言来说,这可能非常令人沮丧。我最近发现自己在使用jqplot时问“函数'draw'中的参数'plot'是什么?”,jqplot是一个相当好但尚未完全记录的JavaScript库。我不得不花一两个小时来挖掘源代码,最后放弃并找到替代解决方案。
重构:使用强类型语言,我发现自己能够通过更改我需要更改的文件然后修复编译器错误来快速重构。有些工具甚至会通过简单地单击按钮来重构。对于弱类型语言,您必须进行搜索,然后小心替换,然后测试,测试,测试,然后测试更多。您很少完全确定自己已经找到并修复了所有损坏的内容,尤其是在大型应用程序中。
对于简单的需求和小型应用程序,这两个问题很少甚至不存在。但是,如果您正在使用具有100千或数百万行代码的应用程序,那么弱类型语言会让您发疯。
我认为许多开发人员对此感到不安,并将其变成一种情绪化的讨论,因为我们有时会在脑海中发现有一种对一错的方法。但每种方法都有其优点 - 其自身的优点和缺点。一旦你认识到你把情绪放在一边,选择最适合你的东西来满足你现在的需求。