Answers:
这种讨论的问题很简单,就是术语“弱类型”和“强类型”是不确定的,与术语“静态类型”,“动态类型”,“显式类型”,“隐式类型”,“鸭式”,“结构式”或“标称”。哎呀,甚至仍然是研究和讨论的开放领域的术语“清单类型”和“潜在类型”也可能更好地定义。
因此,直到您的朋友提供了对“弱类型”一词的定义,该定义足够稳定,可以用作讨论的基础,回答这个问题甚至没有任何意义。
不幸的是,除了尼克的回答,没有一个回答者也愿意提供他们的定义,并且您可以看到某些评论中产生的混乱。很难说,因为实际上没有人提供它们的定义,但是我想我仅在此页面上至少计数了三个不同的定义。
一些更常用的定义是(是的,我知道它们几乎没有任何意义,但是这些是我见过人们实际使用的定义):
然而,似乎最广泛使用的三个定义是
除非大家对什么是“弱类型”即使是同意的定义是,它甚至没有意义的,想想它的优势可能。优点是什么?更糟的是,如果没有定义可言,那么每个人都可以只改变他们的定义,以适应他们的论点,和每一个讨论几乎保证下放成flamewar。
多年来,我本人已经多次更改了自己的定义,而现在我什至不再认为这些术语有用。我还曾经以为弱类型键入(在各种定义中)在Shell脚本中占有一席之地,但是每当我必须在Bash和PowerShell中解决相同的问题时,都会很痛苦地想起我错了。
请记住,有两个主要概念经常被混淆:
当一种编程语言的大部分类型检查在运行时而不是在编译时执行时,就被称为动态类型化。在动态类型化中,值具有类型,而变量则没有。也就是说,变量可以引用任何类型的值。
此处的优点通常不像“新”程序员那样被忽略,但是对于任何程序员来说也很方便:
if (!(arr is Array)) arr = [arr]; // is, instanceof, .constructor ==, whatever
在任何情况下,您不得不强制转换或分配新值的代码将更少:
if (data is Array)) {
i = data.length; // no i = ((Array)data).length or Array myArr=(Array)data;
}
弱类型意味着语言在使用时会隐式转换(或强制转换)类型。
优点:
隐式布尔评估。任何类型都可以评估为布尔值。这也有一些附带好处,例如的一部分||
可以在分配时使用,而无需转换为布尔值:
var a = param || defaultValue;
同样,更少的代码:
var num = 5;
var str = "Hello";
input.innerHTML = input.value = num;
for (var i=0; i < input.value; i++) { ... }
甚至Java也必须走一部分路,.toString()
将对象与String
; 组合在一起时会隐式调用。否则,Java程序员将整日咒骂它(日志语句将失去控制)。
这两个定义均来自http://en.wikipedia.org/wiki/Type_system。它说的比我好。
if
块还是其他更复杂的逻辑(甚至是运行时还是动态的)逻辑,下一行都是合法的并且不会出错。
主要论点为弱打字的性能之一。(这是为了回答OP所述的问题)。关于动态与静态,隐式与显式,有很多很好的讨论。等等
C是最著名的弱类型语言,它不对变量类型执行任何运行时检查或编译时检查。从本质上讲,您可以将a强制转换char *
为an,int *
而该语言将不在乎。那为什么要这么做呢?
C编程非常类似于您使用汇编进行处理的方式,因此有时您只关心地址。void *
出于这种原因,强制转换或传递参考并不少见。如果您知道内存的组织方式(同样是C和汇编语言),则可以根据中的地址进行一些非常酷的计算,void *
以获取所需的信息。例如,这可以使您缩短必须在Java中执行的过程。
尽管运行时类型检查没有太多的开销,但有时它足以使关键部分过慢。在这种情况下,我主要考虑的是嵌入式编程和实时系统。
就是说,在大多数情况下,拥有一个经过编译时间检查或运行时检查的强类型系统,其帮助多于伤害。
对于新手来说,弱类型通常更容易掌握,例如在excel,javascript和vbscript之类的东西中。您还需要以一定的开发速度来换取潜在的错误。
关于该主题的好文章:强类型打字与强测试