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


当前回答

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

静态/动态类型

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

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

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

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

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

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

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

其他回答

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

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

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

什么是强类型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 = "abc" + 123;

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

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

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

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

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

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

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

静态/动态类型

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

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

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

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

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

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

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

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

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