我终于明白了静态和动态打字的区别,你也会明白的!
我终于明白了静态和动态打字的区别,你也会明白的!
当我决定要理解某件事时,我会变得痴迷,直到最终理解为止。我的最新尝试?静态与动态打字。
栈溢出的回答令人困惑,冗长,甚至自相矛盾。原来这些术语经常被误解,所以我的搜索会被证明是困难的是有道理的。我继续阅读我能找到的任何东西,但没有什么能满足我对平易近人和简洁的渴望。
我将从一些基本术语开始,温和地引导你开悟…

RIGHT: “man I should read that article about type systems too…”
编译与解释
“当源代码被翻译时”
- 源代码:原始代码(通常由人输入计算机)
- 翻译:将源代码转换成计算机可读的东西(即机器码)
- 运行时间:程序执行命令的时间(编译后,如果已编译)
- 编译过的:运行前翻译的代码
- 解释的:代码在执行过程中被即时翻译
打字
"检查类型时"
"3" + 5将在强类型语言中引发类型错误,比如 Python 和 Go,因为它们不允许“类型强制”:值在特定上下文中隐式改变类型的能力(例如使用+合并两种类型)。弱类型语言,比如 JavaScript,不会抛出类型错误(结果:'35')。
- 静态:运行前检查的类型
- 动态:在执行过程中动态检查类型
“静态和编译”和“动态和解释”的定义非常相似…但是记住是“当类型被检查时”和“当源代码被翻译时”。
类型检查与正在编译或解释的语言没有任何关系!你需要从概念上区分这些术语。
Python 示例
动态的,解释的
def foo(a):
if a > 0:
print 'Hi'
else:
print "3" + 5foo(2)
因为 Python 是解释型和动态类型的,所以它只对正在执行的代码进行翻译和类型检查。else块从不执行,所以"3" + 5甚至从来没有被看过!
如果它是静态类型的呢?
甚至在代码运行之前就会抛出类型错误。即使被解释,它仍然在运行前执行类型检查。
如果是编的呢?
else块将在运行前被翻译/查看,但是因为它是动态类型的,所以它不会抛出错误!动态类型语言直到执行时才检查类型,而那一行从不执行。
Go 示例
静态的、编译的
package mainimport ("fmt"
)func foo(a int) {
if (a > 0) {
fmt.Println("Hi")
} else {
fmt.Println("3" + 5)
}
}func main() {
foo(2)
}
在运行之前检查类型(静态的),并立即捕捉类型错误!如果类型被解释,在运行前仍然会被检查,结果是一样的。如果它是动态的,即使在编译期间会查看代码,它也不会抛出任何错误。
表演
如果编译的语言是静态类型的,那么它在运行时会有更好的性能,因为类型的知识允许机器代码优化。
静态类型语言本质上在运行时具有更好的性能,因为在执行时不需要动态检查类型(它在运行前检查)。
类似地,编译语言在运行时更快,因为代码已经被翻译,而不需要动态地“解释”/翻译它。
请注意,编译语言和静态类型语言在分别运行翻译和类型检查之前都会有延迟。
更多差异
静态类型在早期捕获错误,而不是在执行过程中发现错误(对于长程序尤其有用)。它更“严格”,因为它不允许程序中的任何地方出现类型错误,并且经常阻止变量改变类型,这进一步防止了意外的错误。
num = 2
num = '3' // ERROR
动态类型更加灵活(有些人很欣赏这一点),但是允许变量改变类型(有时会产生意外的错误)。
这让你明白了吗?请在评论中告诉我!