无论编译语言中的键入(静态与动态)如何,编译期间是否都捕获到错误?

时间:2017-12-05 00:29:33

标签: computer-science typing

以下是解释answerDynamic vs. Static Typing

我很困惑为什么这会演示动态与静态类型,因为我认为编译语言的所有错误都会在编译过程中被捕获,因此无论是静态还是动态类型都无关紧要。

也许这表明静态类型的语言总是在运行之前引发错误,动态类型总是会在执行期间引发错误而不管它是否被编译或解释?

有人可以更深入地解释这个吗?

  

这是一个对比Python(动态类型)和Go的示例   (静态类型)处理类型错误:

def silly(a):
    if a > 0:
        print 'Hi'
    else:
        print 5 + '3'
     

Python在运行时进行类型检查,因此:

silly(2)
     

运行完全正常,并产生预期的输出Hi。只有在遇到有问题的行时才会出错:

silly(-1) 
     

可生产

     
TypeError: unsupported operand type(s) for +: 'int' and 'str'
  
     

因为实际执行了相关的行。

     

另一方面,在编译时进行类型检查:

package main

import ("fmt"
)

func silly(a int) {
  if (a > 0) {
      fmt.Println("Hi")
  } else {
      fmt.Println("3" + 5)
  }
}

func main() {
  silly(2)
} 
     

以上将无法编译,并出现以下错误:

     
invalid operation: "3" + 5 (mismatched types string and int)
  

2 个答案:

答案 0 :(得分:2)

已编译< - >解释的尺度与动态< - >完全正交。静态打字量表。 (可能另一个编译时类型的正交标度检查和运行时类型检查)

例如,您可以使用Cython将示例中的Python脚本编译为本机二进制文件。它将以完全相同的方式工作,但它将被编译。也可以使用mypy提前对Python脚本进行类型检查,并使用提供运行时类型异常的CPython运行。

另一方面,您可以在代码执行之前安装具有静态类型和交互式shell(解释器)的语言并尝试使用类似的表达式you'll get a type error。这部分有点令人困惑,因为要获得类型错误,你需要在某种程度上编译代码(进入AST和类型检查),但我认为它不符合“编译”的通用定义。

总之,您可以编译动态类型,静态编译,动态类型解释和静态类型解释。 (并且来自repl的链接示例可以说它是关于强类型 - 随意提供更好的一个)

答案 1 :(得分:0)

否。除非语言是静态类型,否则不会在编译中捕获类型错误。

请注意,无论键入什么,编译都会捕获语法错误

这个例子令人困惑,因为它结合了静电& amp;编译"与"动态&解释"这模糊了不同类型系统的影响。

  • 去做示例如果它是动态类型,尽管被编译,也不会抛出错误!
  • Python示例如果静态类型,则抛出错误,即使该行永远不会被解释!

类型检查与正在编译或解释的语言无关!

我将回顾基本概念,然后深入研究这个例子。

编译与解释

"翻译源代码"

  • 源代码:原始代码(通常由人类输入计算机)
  • 翻译:将源代码转换为计算机可以读取的内容(即机器代码)
  • 运行时:程序执行命令的时间段(编译后,如果已编译)
  • 编译语言:在运行时翻译的代码
  • 口译语言:执行期间即时翻译的代码

输入

"检查类型"

5 + '3'强类型语言(如Go和Python)中类型错误的一个示例,因为它们不允许"类型强制" - >值在某些上下文中更改类型的能力,例如合并两种类型。 弱类型的语言(例如JavaScript)不会抛出类型错误(导致'53')。

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

"静态& amp;的定义编译"和"动态&解释"非常相似...但请记住它的类型,检查类型" vs."当源代码被翻译时#34;。

无论语言是编译还是解释,您都会遇到相同类型的错误!您需要在概念上区分这些术语。

Python示例

动态,解释

def silly(a):
    if a > 0:
        print 'Hi'
    else:
        print 5 + '3'

silly(2)

因为Python既被解释又被动态地键入,因此它只对它正在执行的代码进行翻译和类型检查。 else块永远不会执行,所以5 + '3'永远不会被查看!

如果是静态类型怎么办?

在代码运行之前会抛出类型错误。它仍然在运行时执行类型检查,即使它被解释。

如果编译了怎么办?

else块将在运行时被翻译/查看,但由于它是动态输入的,因此不会抛出错误!动态类型语言在执行之前不会检查类型,并且该行永远不会执行。

Go Example

静态,已编译

package main

import ("fmt"
)

func silly(a int) {
  if (a > 0) {
      fmt.Println("Hi")
  } else {
      fmt.Println("3" + 5)
  }
}

func main() {
  silly(2)
}

在运行之前检查类型(静态),并立即捕获类型错误!如果解释了类型,则在运行时仍会检查这些类型,结果相同。如果它是动态的,即使在编译期间查看代码,它也不会抛出任何错误。

效果

如果编译语言的静态类型(动态对比),则它在运行时会有更好的性能;类型知识允许机器代码优化。

静态类型语言在运行时本质上具有更好的性能,因为不需要在执行时动态检查类型(它在运行之前检查)。

类似地,编译语言在运行时更快,因为代码已经被翻译而不是需要"解释" /在运行中翻译它。

请注意,编译和静态类型语言在运行转换和类型检查之前都会有延迟。

更多差异

静态类型提前捕获错误,而不是在执行期间找到它们(对于长程序尤其有用)。它更严格"严格"因为它不会在程序中的任何地方允许类型错误,并且通常会阻止变量更改类型,从而进一步防止意外错误。

num = 2
num = '3' // ERROR

动态打字更灵活,有些人欣赏。它通常允许变量更改类型,这可能导致意外错误。

相关问题