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


当前回答

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

强类型与弱类型 静态类型vs.动态类型

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

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

其他回答

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

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

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

上面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.

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

答案已经在上面给出了。试图区分强与周,静态与动态的概念。

什么是强类型VS弱类型?

强类型:不会自动从一种类型转换为另一种类型

在Go或Python这样的强类型语言中,“2”+ 8会引发类型错误,因为它们不允许“类型强制”。

弱类型(松散类型):将自动转换为一种类型为另一种类型: 弱类型语言(如JavaScript或Perl)不会抛出错误,在这种情况下,JavaScript的结果是'28',Perl的结果是10。

Perl的例子:

my $a = "2" + 8;
print $a,"\n";

将其保存到main.pl并运行perl main.pl,您将得到输出10。

什么是静态和动态类型?

在编程中,程序员根据检查变量类型的点来定义静态类型和动态类型。静态类型语言是指在编译时进行类型检查的语言,而动态类型语言是指在运行时进行类型检查的语言。

静态:运行前检查的类型 动态:在执行期间动态检查类型

这是什么意思?

在Go中,它在运行前检查输入(静态检查)。这意味着它不仅翻译和类型检查它正在执行的代码,而且它将扫描所有的代码,甚至在代码运行之前就会抛出类型错误。例如,

package main

import "fmt"

func foo(a int) {
    if (a > 0) {
        fmt.Println("I am feeling lucky (maybe).")
    } else {
        fmt.Println("2" + 8)
    }
}

func main() {
    foo(2)
}

在main中保存此文件。去运行它,你会得到编译失败的消息。

go run main.go
# command-line-arguments
./main.go:9:25: cannot convert "2" (type untyped string) to type int
./main.go:9:25: invalid operation: "2" + 8 (mismatched types string and int)

但这种情况不适用于Python。例如,下面的代码块将在第一次foo(2)调用时执行,而在第二次foo(0)调用时失败。这是因为Python是动态类型的,它只翻译和类型检查它所执行的代码。对于foo(2), else块从未执行,因此“2”+ 8甚至从未被查看,对于foo(0)调用,它将尝试执行该块,但失败。

def foo(a):
    if a > 0:
        print 'I am feeling lucky.'
    else:
        print "2" + 8
foo(2)
foo(0)

您将看到以下输出

python main.py
I am feeling lucky.
Traceback (most recent call last):
  File "pyth.py", line 7, in <module>
    foo(0)
  File "pyth.py", line 5, in foo
    print "2" + 8
TypeError: cannot concatenate 'str' and 'int' objects

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

静态/动态类型

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

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

以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强/弱

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

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

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

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