我是PHP的忠实粉丝,它显然是一种非常弱类型的语言。我意识到一些好处包括动态改变变量类型的一般独立性等。
我想知道的是缺点。你能从C这样的强类型语言中得到什么呢?否则你无法从像PHP这样的弱类型语言中获得这种语言?还有类型设置(如double($ variable)),人们可以争辩说,即使是弱类型语言也可以像强类型语言一样。
因此。弱型。我没有包括哪些好处?更重要的是,有哪些缺点?
答案 0 :(得分:11)
静态输入的优点是,在编译时捕获了整个类错误,无法达到运行时。例如,如果你有一个静态类型的类或接口作为函数参数,那么你不会意外地传入一个错误类型的对象(没有明确和错误的转换,即)。
当然,这并不能阻止你传入正确类型的错误对象,或者是一个接口的实现,你已经为它提供了正确的功能,但它们做错了。此外,如果你有100%的代码覆盖率,比如说PHP / Python /等人,你是否关心你是在编译时还是在运行时捕获错误?
就个人而言,我在使用静态打字的语言中度过了愉快的时光,并且在没有语言的情况下玩得很开心。这很少是决定性的问题,因为我从来没有必须在两种语言之间进行选择,这些语言除了打字之外都是相同的,通常还有更重要的事情需要担心。我确实发现,当我使用静态类型语言时,我故意“依赖于编译器”,试图以这样的方式编写代码:如果它错了,它将无法编译。例如,您可以通过在一个位置进行更改来执行某些重构,然后修复导致的所有编译错误,重复直到清除编译。通过多次运行完整的测试套件来做同样的事情可能不太实际。但是,IDE在其他语言中自动化相同的重构,或者快速完成测试并不是闻所未闻的,所以这是一个方便的问题,而不是可能的问题。
那些在方便性和编码风格偏好之外有合理关注的人是那些致力于正式证明代码正确性的人。我的无知印象是,静态类型演绎可以完成显式静态打字所做的大部分(但不是全部)工作,并且可以节省键盘上相当大的磨损。所以如果静态类型强迫人们以更容易证明的方式编写代码,那么那么就可以从那个POV中找到它。我说“if”:我不知道,并不是说大多数人都会证明他们的静态类型代码。
动态更改变量类型
我认为这是值得怀疑的。像(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 ++中决定是否实现转换运算符和非显式单arg构造函数的持续困难。
答案 1 :(得分:2)
我一直在使用强类型(如Java)和弱类型(如JavaScript)语言。我发现弱类型语言的便利性对于小型应用程序来说非常有用。不幸的是,随着应用程序规模的扩大,管理变得不可能。有太多的东西要跟踪你的头脑,你必须开始依赖你的IDE和编译器越来越多或你的编码停止。这就是强类型语言开始变得更有用的时候 - 应用程序变得非常大。
在弱类型JavaScript中经常让我疯狂的两个例子是使用未完全记录和重构的外部库。
外部库:在处理强类型语言时,库本身的代码提供自我文档。当我创建Person类型的变量时,IDE可以检查代码并告诉它有一个getFirstName(),getLastName()和getFullName()。在弱类型语言中,情况并非如此,因为变量可以是任何类型,具有任何类型的变量或函数,并且具有也可以是任何事物的函数参数(它们未被明确定义)。因此,开发人员必须严重依赖文档,网络搜索,论坛以及他们对过去使用的记忆。我发现使用Java可能需要花费数小时才能查找外部库,而使用Java时我只需点击“。”键,它会弹出我附带的文档的所有选项。当您遇到未完全记录的库时,弱类型语言可能会令人沮丧。我最近发现自己在函数'draw'中询问“什么是参数'情节'?”当使用jqplot时,这是一个相当好但未完全记录的JavaScript库。在最终放弃并找到替代解决方案之前,我不得不花费一两个小时来挖掘源代码。
重构:使用强类型语言,我发现自己能够通过更改我需要更改的文件来快速重构,然后修复编译器错误。只需单击一下按钮,有些工具甚至可以为您重构。使用弱类型语言,您必须进行搜索,然后小心替换,然后测试,测试,测试,然后再测试一些。你很少完全确定你找到并修复了你所破坏的一切,特别是在大型应用程序中。
对于简单需求和小型应用程序,这两个问题很少到根本不存在。但是,如果您正在使用具有数百或数百万行代码的应用程序,那么弱类型语言将使您疯狂。
我认为很多开发人员对此感到不安并将其变成情绪化的讨论是因为我们有时会认为有一种正确和一种错误的方法。但每种方法都有其优点 - 各有利弊。一旦你认识到你把情绪放在一边,并为你现在所需的选择最好的。
答案 2 :(得分:1)
有很多关于这类事的书。有一个固有的权衡;使用弱类型的语言,很多烦恼就会停止。例如,在Python中,您永远不必担心将float
除以int
; 将输入函数的参数(您知道吗,OCaml有用于添加int
添加到list
; float
的特殊+。运算符,因为{{1} }将(+)
发送给int
s!);忘记变量可以为null ......那些问题只是消失了。
取而代之的是一系列新的运行时错误:Python的int
给出,等待它,[0]*5
!对于强类型的所有烦恼,OCaml通过其编译器捕获了许多许多错误;这正是它为什么好的原因。这是一个权衡。
答案 3 :(得分:1)
弱和强是加载条款。 (你想成为一个弱语言程序员吗?)动态和静态更好但我想大多数人宁愿成为一个动态程序员而不是静态程序员。我会称PHP是一种混杂的语言(这不是一个加载的术语;))
PHP:
garbage_out = garbage_in * 3; // garbage_in was not initialized yet
"hello world" + 2; // does this make sense?
允许未初始化的变量很难从拼写错误中找到错误。允许对不相关类型的操作也几乎总是应该报告的错误。大多数解释动态语言都不允许出于这些原因。您可以使用动态类型语言而不允许垃圾。
答案 4 :(得分:1)
请参阅this table,其中显示了应用于各种类型的空或其他主要值对的PHP ==
运算符的结果,例如0
,"0"
,{ {1}}和NULL
。操作员是非交换的,至少可以说这个表是非常不直观的。 (并不是说公平地询问一个字符串是否等于一个数组是有意义的 - 但你可以用弱类型语言来做这个,这是一个陷阱,并且可能图灵帮助你,如果语言试图“帮助”你。)
答案 5 :(得分:0)
直接来自维基百科:
声称弱打字的优势 是因为它需要更少的努力 程序员的一部分比强 打字,因为编译器或 解释器隐含地执行 某些类型的转换。然而, 一个声称的缺点是 弱类型编程系统捕获 在编译时和一些错误更少 这些可能仍然存在 测试已经完成。
我会说同样的事情。但请注意这些术语的相对含糊之处(“强类型”和“弱打字”),因为隐式转换模糊了这一行。
答案 6 :(得分:0)
您必须了解PHP是为Web应用程序的上下文创建的。 Web上下文中的所有内容都是字符串。因此,强力打字是有益的。