另外,一个暗示另一个吗?

有帮助吗?

解决方案

强烈键入的语言和静态键入语言有什么区别?

静态键入的语言具有一个类型系统,该系统在编译时通过实现(编译器或解释器)进行了检查。该类型检查拒绝了一些程序,并且通过支票的程序通常带有一些保证;例如,编译器保证不要在浮点数上使用整数算法指令。

尽管专业文献中最广泛使用的定义是,在“强烈键入”的语言中,程序员不可能解决类型系统施加的限制,但对“强烈使用的定义”没有真正的共识,尽管专业文献中使用了最广泛使用的定义。该术语几乎总是用来描述静态类型的语言。

静态与动态

静态键入的相反是“动态键入”,这意味着

  1. 运行时间使用的值分为类型。
  2. 关于如何使用此类值有限制。
  3. 当违反这些限制时,违规被报告为(动态)类型错误。

例如, 卢阿, ,一种动态键入的语言,具有字符串类型,一个数字类型和布尔值类型。在lua中,每个值属于 确切地 一种类型,但这并不是所有动态键入语言的要求。在Lua中,可以加入两个字符串,但不允许连接串和布尔值。

强力与弱者

“强烈键入”的对立面是“弱键入”,这意味着您可以在类型系统周围工作。众所周知,C键入薄弱,因为任何指针类型都可以通过铸造简单地转换为任何其他指针类型。帕斯卡(Pascal)旨在强烈键入,但是设计(未标记的变体记录)的监督将漏洞引入了类型系统中,因此从技术上讲,它是薄弱的。真正强烈打字的语言的示例包括CLU,Standard ML和Haskell。实际上,标准ML经过了几次修订,以消除该语言被广泛部署后发现的类型系统中的漏洞。

这里真的发生了什么?

总体而言,谈论“强”和“弱”并不是那么有用。一种类型系统是否具有漏洞不如漏洞的确切数量和性质,在实践中出现的可能性以及利用漏洞的后果是什么。在实践中, 最好避免完全避免“强”和“弱”术语, , 因为

  • 业余爱好者经常将它们与“静态”和“动态”混为一谈。

  • 显然,某些人使用“弱打字”来谈论相对流行或没有隐性转换。

  • 专业人士无法确切地同意该条款的含义。

  • 总体而言,您不太可能告知或启发您的受众。

可悲的事实是,在类型系统方面, “强”和“弱”没有普遍同意的技术意义。 如果您想讨论类型系统的相对强度,最好确切地讨论什么保证和未提供的保证。例如,一个好问题要问的是:“是否通过调用该类型的一个构造函数之一来保证创建的给定类型(或类)的每个值?”在C中,答案是否定的。在Clu,F#和Haskell中,是的。对于C ++,我不确定 - 我想知道。

相比之下, 静态打字 意味着程序是 在执行之前检查, ,并且在程序开始之前可能会拒绝程序。 动态键入 意味着类型 被检查 执行,键入不良的操作可能会导致程序在运行时停止或以其他方式发出信号。静态键入的主要原因是排除可能具有这种“动态类型错误”的程序。

一个暗示另一个吗?

在典范上,不,因为“强”一词并没有任何意义。但是实际上,人们几乎总是做两件事之一:

  • 他们(错误地)使用“强”和“弱”来表示“静态”和“动态”,在这种情况下,他们(错误地)使用“强键入”和“静态键入”。

  • 他们使用“强”和“弱”来比较静态类型系统的属性。听到有人谈论“强”或“弱”的动态类型系统,这是非常罕见的。除了Fort,它实际上没有任何类型的系统,我想不出可以颠覆类型系统的动态键入语言。从定义上讲,这些检查是在执行引擎中造成的,并且在执行之前,每个操作都会检查理智。

无论哪种方式,如果一个人将一种语言称为“强烈键入”,那么该人很可能会谈论一种静态键入的语言。

其他提示

这常常被误解,所以让我清除它。

静态/动态键入

静态打字 是类型绑定到的地方 多变的. 。在编译时检查类型。

动态键入 是类型绑定到的地方 价值. 。在运行时检查类型。

因此,在Java中:

String s = "abcd";

s 将“永远”成为一个 String. 。在生命中,它可能指出不同的 StringS(自从 s 是Java中的参考)。它可能有一个 null 价值,但它永远不会指 Integer 或a 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

那是动态的打字。

强/弱打字

(编辑警报!)

强大的打字 是一个没有广泛同意的含义的短语。大多数使用该术语含义静态键入以外的内容的程序员都使用它来暗示编译器强制执行的类型纪律。例如,CLU具有强大的类型系统,该系统不允许客户端代码创建抽象类型的值,除非使用类型提供的构造函数。 C具有一个强大的类型系统,但是可以在某种程度上“颠覆”,因为程序总是可以将一种指针类型的值投放到另一种指针类型的值。因此,例如,在C中,您可以取一个值 malloc() 并欣喜地把它扔给 FILE*, ,而且编译器不会试图阻止您,甚至警告您您正在做任何狡猾的事情。

(原始答案说了一些价值“在运行时不更改类型”。我认识了许多语言设计师和编译器作家,并且不知道有人谈论在运行时更改价值的人,但可能是一些类型的一些非常高级的研究系统,其中称为“强更新问题”。)

弱打字 暗示编译器不会强制执行打字截图,或者可能很容易颠覆执行。

这个答案的原始内容将弱打字与 隐式转换 (有时也称为“隐性促销”)。例如,在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 因此,条件实际上是正确的。解决方案是使用 === 代替 == 避免隐式转换。

此示例说明了隐式转换和动态键入的组合如何使程序员误入歧途。

将其与Ruby进行比较:

val = "abc" + 123

这是一个运行时错误,因为在Ruby中 目的 123是 不是 隐式转换只是因为它恰好传递给 + 方法。在Ruby中,程序员必须显式转换:

val = "abc" + 123.to_s

在这里比较PHP和Ruby是一个很好的例证。两者都是动态键入的语言,但是PHP具有许多隐性转换,Ruby(如果您不熟悉它,也许令人惊讶)不会。

静态/动态与强/弱

这里的观点是静态/动态轴独立于强/弱轴。人们之所以混淆他们可能部分是因为强大的与弱打字不仅是明确定义的,而且对坚强和弱的含义完全没有共识。因此,强/弱打字更像是灰色的阴影,而不是黑色或白色。

因此要回答您的问题:另一种看待这个问题的方法 大多 正确的是说静态键入是编译时类型安全性,并且强大的打字是运行时类型的安全性。

这样做的原因是,静态类型语言中的变量具有必须声明的类型,并且可以在编译时检查。强大的语言具有在运行时具有类型的值,而且程序员很难在没有动态检查的情况下颠覆类型系统。

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

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

  • 强烈键入与弱输入
  • 静态键入与动态键入

强烈键入 含义,A不会自动从一种类型转换为另一种类型。弱键入的恰恰相反:Perl可以使用类似的字符串 "123" 在数字上下文中,通过自动将其转换为int 123. 。像Python这样的强烈打字语言不会这样做。

静态打字 均值,编译器在编译时算出每个变量的类型。动态键入的语言仅在运行时找出变量的类型。

强烈键入意味着类型之间的转换之间存在限制。静态键入意味着类型不是动态的 - 创建变量后,您将无法更改其类型。

数据强制并不一定意味着弱键入,因为有时其语法糖:

上面的Java的示例由于弱输入

String s = "abc" + 123;

不是弱输入的例子,因为它确实这样做:

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

如果您要构建一个新对象,则数据强制也不会弱输入。 Java是弱输入的一个非常糟糕的例子(任何具有良好反映的语言很可能不会被弱输入)。因为语言的运行时间总是知道类型是什么(例外可能是本地类型)。

这与C。C是弱输入的最佳例子之一。运行时不知道4个字节是整数,结构,指针还是4个字符。

该语言的运行时间确实定义了其是否弱输入,否则它确实只是意见。

编辑:在进一步认为这不一定是正确的之后,因为运行时不必将运行时系统中的所有类型重新列为强大的系统。 Haskell和ML具有如此完整的静态分析,以至于它们可以从运行时潜在的OMMIT类型信息。

一个并不意味着另一个。语言是 静态 键入意味着所有变量的类型在编译时已知或推断。

一种 强烈 键入语言不允许您将一种类型用作另一种类型。 C是一种弱打字的语言,是强烈键入语言不允许的一个很好的例子。在C中,您可以传递错误类型的数据元素,并且不会抱怨。在强烈的类型语言中,您不能。

强大的键入可能意味着变量具有明确的类型,并且在结合表达式不同类型的变量方面存在严格的规则。例如,如果A是整数,而B是浮点,则有关A+B的严格规则可能是A将A铸成浮点,结果返回为浮点。如果A是整数,而B是字符串,则严格的规则可能是A+B无效。

静态键入可能意味着类型是在编译时(或其等效的非编译语言)分配的,并且在程序执行过程中无法更改。

请注意,这些分类不是相互排斥的,实际上,我希望它们会经常一起发生。许多强大的语言也在静态上型。

并请注意,当我使用“可能”一词时,这是因为这些术语没有普遍接受的定义。从到目前为止,您已经从答案中看到了。

答案已在上面给出。试图区分强度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。

什么是静态与Dyamic类型?

在编程中,Progammer定义了检查变量类型的点。静态键入语言是在编译时进行类型检查的语言,而动态键入语言是在运行时完成类型检查的语言。

  • 静态:运行时间之前检查的类型
  • 动态:执行期间即时检查类型

这是什么意思?

在运行时间之前输入的检查(静态检查)。这意味着它不仅翻译和类型检查代码正在执行,而且还会在代码运行之前扫描所有代码和类型错误。例如,

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中并运行它,您将获得汇编失败的消息。

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),因此“ 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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top