以下是解释answer的Dynamic 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)
答案 0 :(得分:2)
已编译< - >解释的尺度与动态< - >完全正交。静态打字量表。 (可能另一个编译时类型的正交标度检查和运行时类型检查)
例如,您可以使用Cython将示例中的Python脚本编译为本机二进制文件。它将以完全相同的方式工作,但它将被编译。也可以使用mypy
提前对Python脚本进行类型检查,并使用提供运行时类型异常的CPython运行。
另一方面,您可以在代码执行之前安装具有静态类型和交互式shell(解释器)的语言并尝试使用类似的表达式you'll get a type error。这部分有点令人困惑,因为要获得类型错误,你需要在某种程度上编译代码(进入AST和类型检查),但我认为它不符合“编译”的通用定义。
总之,您可以编译动态类型,静态编译,动态类型解释和静态类型解释。 (并且来自repl的链接示例可以说它是关于强类型 - 随意提供更好的一个)
答案 1 :(得分:0)
否。除非语言是静态类型,否则不会在编译中捕获类型错误。
请注意,无论键入什么,编译都会捕获语法错误。
这个例子令人困惑,因为它结合了静电& amp;编译"与"动态&解释"这模糊了不同类型系统的影响。
类型检查与正在编译或解释的语言无关!
我将回顾基本概念,然后深入研究这个例子。
"翻译源代码"
"检查类型"
5 + '3'
是强类型语言(如Go和Python)中类型错误的一个示例,因为它们不允许"类型强制" - >值在某些上下文中更改类型的能力,例如合并两种类型。 弱类型的语言(例如JavaScript)不会抛出类型错误(导致'53'
)。
"静态& amp;的定义编译"和"动态&解释"非常相似...但请记住它的类型,检查类型" vs."当源代码被翻译时#34;。
无论语言是编译还是解释,您都会遇到相同类型的错误!您需要在概念上区分这些术语。
动态,解释
def silly(a):
if a > 0:
print 'Hi'
else:
print 5 + '3'
silly(2)
因为Python既被解释又被动态地键入,因此它只对它正在执行的代码进行翻译和类型检查。 else
块永远不会执行,所以5 + '3'
永远不会被查看!
如果是静态类型怎么办?
在代码运行之前会抛出类型错误。它仍然在运行时执行类型检查,即使它被解释。
如果编译了怎么办?
else
块将在运行时被翻译/查看,但由于它是动态输入的,因此不会抛出错误!动态类型语言在执行之前不会检查类型,并且该行永远不会执行。
静态,已编译
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
动态打字更灵活,有些人欣赏。它通常允许变量更改类型,这可能导致意外错误。