另外,两者之间是否存在关联?


当前回答

数据强制并不一定意味着弱类型,因为有时它的语法糖:

上面Java的例子是弱类型的,因为

String s = "abc" + 123;

不是弱类型的例子,因为它真正做的是:

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

如果您正在构造一个新对象,数据强制也不是弱类型的。 Java是弱类型的一个非常糟糕的例子(任何具有良好反射的语言都很可能不是弱类型的)。因为语言的运行时总是知道类型是什么(异常可能是本机类型)。

这与C不同。C是弱类型的最佳示例之一。运行时不知道4字节是整数、结构体、指针还是4个字符。

语言的运行时真正定义了它是否弱类型,否则它只是意见。

编辑: 经过进一步思考,这并不一定是正确的,因为运行时不必在运行时系统中具体化所有类型才能成为强类型系统。 Haskell和ML有这样完整的静态分析,它们可以潜在地从运行时提交类型信息。

其他回答

强类型意味着类型之间的转换之间存在限制。

静态类型意味着类型不是动态的——一旦创建了变量,就不能更改变量的类型。

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

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

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

静态vs动态

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

在运行时使用的值被分为不同的类型。 对于如何使用这些值有一些限制。 当违反这些限制时,违反将作为(动态)类型错误报告。

例如,动态类型语言Lua具有字符串类型、数字类型和布尔类型等。在Lua中,每个值都只属于一种类型,但这并不是所有动态类型语言都必须这样做。在Lua中,允许连接两个字符串,但不允许连接字符串和布尔值。

强与弱

The opposite of "strongly typed" is "weakly typed", which means you can work around the type system. C is notoriously weakly typed because any pointer type is convertible to any other pointer type simply by casting. Pascal was intended to be strongly typed, but an oversight in the design (untagged variant records) introduced a loophole into the type system, so technically it is weakly typed. Examples of truly strongly typed languages include CLU, Standard ML, and Haskell. Standard ML has in fact undergone several revisions to remove loopholes in the type system that were discovered after the language was widely deployed.

这里到底发生了什么?

总的来说,讨论“强”和“弱”并没有那么有用。一个类型系统是否存在漏洞,重要的是漏洞的确切数量和性质,它们在实践中出现的可能性,以及利用漏洞的后果。在实践中,最好避免使用“强”和“弱”这两个词,因为

业余爱好者经常把它们与“静态”和“动态”混为一谈。 显然,有些人用“弱类型”来谈论隐式转换的相对流行或缺乏。 专业人士无法就这些术语的确切含义达成一致。 总的来说,你不太可能告诉或启发你的观众。

The sad truth is that when it comes to type systems, "strong" and "weak" don't have a universally agreed on technical meaning. If you want to discuss the relative strength of type systems, it is better to discuss exactly what guarantees are and are not provided. For example, a good question to ask is this: "is every value of a given type (or class) guaranteed to have been created by calling one of that type's constructors?" In C the answer is no. In CLU, F#, and Haskell it is yes. For C++ I am not sure—I would like to know.

相比之下,静态类型意味着程序在执行之前要进行检查,并且程序可能在开始之前就被拒绝。动态类型意味着在执行期间检查值的类型,类型不佳的操作可能导致程序在运行时停止或发出错误信号。使用静态类型的一个主要原因是排除可能存在这种“动态类型错误”的程序。

两者之间是否有关联?

从学究的角度来说,没有,因为“强大”这个词其实没有任何意义。但实际上,人们几乎总是做两件事中的一件:

They (incorrectly) use "strong" and "weak" to mean "static" and "dynamic", in which case they (incorrectly) are using "strongly typed" and "statically typed" interchangeably. They use "strong" and "weak" to compare properties of static type systems. It is very rare to hear someone talk about a "strong" or "weak" dynamic type system. Except for FORTH, which doesn't really have any sort of a type system, I can't think of a dynamically typed language where the type system can be subverted. Sort of by definition, those checks are bulit into the execution engine, and every operation gets checked for sanity before being executed.

不管怎样,如果有人称一种语言为“强类型”,那么这个人很可能是在谈论一种静态类型的语言。

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

静态/动态类型

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

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

以Java为例:

String s = "abcd";

s将“永远”是一个字符串。在它的生命周期中,它可以指向不同的字符串(因为s是Java中的引用)。它可能有一个空值,但它永远不会引用一个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

这就是动态类型。

强/弱类型

(编辑提醒!)

Strong typing is a phrase with no widely agreed upon meaning. Most programmers who use this term to mean something other than static typing use it to imply that there is a type discipline that is enforced by the compiler. For example, CLU has a strong type system that does not allow client code to create a value of abstract type except by using the constructors provided by the type. C has a somewhat strong type system, but it can be "subverted" to a degree because a program can always cast a value of one pointer type to a value of another pointer type. So for example, in C you can take a value returned by malloc() and cheerfully cast it to FILE*, and the compiler won't try to stop you—or even warn you that you are doing anything dodgy.

(最初的答案说了一些关于值“在运行时不改变类型”的内容。我认识许多语言设计者和编译器作者,但没有一个人谈论过在运行时改变类型的值,除了一些类型系统的非常高级的研究,在那里这被称为“强更新问题”。)

弱类型意味着编译器不强制执行类型规则,或者这种强制很容易被破坏。

这个答案的最初将弱类型与隐式转换(有时也称为“隐式提升”)混为一谈。例如,在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(如果您不熟悉它,可能会感到惊讶)没有。

静态/动态vs强/弱

这里的重点是静态/动态轴独立于强/弱轴。人们混淆它们的部分原因可能是强类型和弱类型不仅定义不明确,而且对于强类型和弱类型的确切含义也没有真正的共识。因此,强/弱类型更像是灰色的阴影,而不是黑色或白色。

所以回答你的问题:另一种看待这个问题的最正确的方法是说静态类型是编译时类型安全,强类型是运行时类型安全。

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

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

恕我直言,最好完全避免这些定义,不仅没有一致的术语定义,确实存在的定义倾向于关注技术方面,例如,混合类型上的操作是否允许,如果不允许,是否存在绕过限制的漏洞,例如使用指针工作。

相反,再次强调这是一种观点,人们应该关注这个问题:类型系统是否使我的应用程序更可靠?一个特定于应用程序的问题。

例如:如果我的应用程序有一个名为加速度的变量,那么显然,如果变量的声明和使用方式允许将值“星期一”分配给加速度,这是一个问题,因为显然加速度不能是工作日(和字符串)。

Another example: In Ada one can define: subtype Month_Day is Integer range 1..31;, The type Month_Day is weak in the sense that it is not a separate type from Integer (because it is a subtype), however it is restricted to the range 1..31. In contrast: type Month_Day is new Integer; will create a distinct type, which is strong in the sense that that it cannot be mixed with integers without explicit casting - but it is not restricted and can receive the value -17 which is senseless. So technically it is stronger, but is less reliable. Of course, one can declare type Month_Day is new Integer range 1..31; to create a type which is distinct and restricted.

一个并不意味着另一个。对于静态类型的语言来说,这意味着所有变量的类型都是在编译时已知或推断出来的。

强类型语言不允许将一种类型用作另一种类型。C是一种弱类型语言,是强类型语言不允许的一个很好的例子。在C语言中,你可以传递错误类型的数据元素,它不会报错。在强类型语言中你不能这样做。