如果我们看看维基百科中“动态类型编程语言”的定义,它会说:
编程语言包括动态类型检查而不是静态类型检查,通常被称为“动态类型编程语言”。
和
动态类型检查是在运行时验证程序类型安全性的过程.动态类型检查语言的实现通常将每个运行时对象与包含其类型信息的“类型标记”(即对类型的引用)关联起来。此运行时类型信息(RTTI)还可用于实现动态调度、后期绑定、下传、反射和类似功能。
但是问题是,当使用时,我从来没有看到类型被“检查”。
在我之前看过的一段视频中,作者说静态类型只是指定义/声明和编译变量的类型,不能更改,而动态类型意味着在程序运行时变量的类型可以随时更改,我看到它描述静态/动态类型非常清楚和简单。
实际上,根据GoF,类型只是一组接口,所以除了它是否响应特定的消息之外,您如何“检查”该类型?也就是说,当使用动态类型语言时,我并不像在“动态类型检查”中那样看到它。检查是什么时候进行的?
发布于 2016-01-10 01:46:36
Javascript:
>>> 1()
TypeError: 1 is not a function红宝石:
>>> 1 + ""
String can't be coerced into Fixnum这都是动态类型错误的简单情况。许多语言,包括几乎所有的动态语言,但也包括,例如C#和Java,做“类型标记”。也就是说,这些环境的运行时实际上必须将类型的表示附加到每个对象。这与静态类型不同,因为类型标记存在于运行时,并且至少在动态命令式语言(如Ruby和Javascript )中,一个变量可能指向不同类型的不同对象。
为了实现语言的语义,运行时必须始终检查这些类型标记。例如,在对两个对象执行+操作时,这些语言会检查两个对象的类型标记,以决定要做什么。如果这两个对象都被标记为数字,那么将执行加法(可能是在某些类型转换为普通数字类型之后)。如果两个对象都被标记为string类型标记,则执行字符串连接。(可能让您绊倒的是Javascript将在正常操作中执行大量的运行时类型转换。这使得它看起来不像是在检查类型标签,因为没有引发类型错误,而实际上,类型标记是在各地检查以执行这些转换的。)
请注意,这种类型标签检查只具有与(静态)类型检查的模糊和误导性的相似之处。静态类型检查在运行时之前检查表达式的属性,而类型标记检查检查表达式在运行时表示的值的属性。Ruby和Javascript都在它们的基本运行时环境(例如,在+、-、函数调用中)执行类型标记检查。它们还允许语言的用户执行类型标签内省。也就是说,它们允许用户在运行时检查值的类型标记。
实际上,根据GoF,类型只是一组接口,所以除了它是否响应特定的消息之外,您如何“检查”该类型?
我不熟悉这个定义,但在我看来,这是一种误导。静态类型是根据一组类型规则与一种语言中的表达式相关联的令牌,用于定义在该语言中哪些表达式在语义上是有效的。“动态类型”(如我所喜欢的类型标记)是一个与语言运行时中的对象相关联的值。在某种意义上,两者都与接口相关联。在静态类型语言中,类型定义该类型的表达式可能合法地出现在哪些表达式中,因此在此范围内确定该类型的接口。类似地,类型标记也在一定程度上决定,在尝试操作之前,哪些操作将以运行时"TypeError“结尾。
然而,在大多数静态动态语言中识别类型/类型标签及其接口是一种误导。基本上,所有静态和动态语言基本上都是名义上的,而不是结构类型的。也就是说,在普通静态类型语言中,如果定义了类型YourCustomer而我定义了MyCustomer,则这两种类型的表达式将不可互换。即使YourCustomer和MyCustomer的定义在命名上是相同的。类似地,如果使用类型标记YourJSCustomer定义Javascript对象,而我使用类型标记MyJSCustomer定义Javascript对象,即使这两个对象具有所有相同的属性和方法,否则它们在类型标签内省面前是不可互换的。
的确,在许多动态类型语言中,类型标记内省并不总是被使用,因此YourJSCustomer和MyJSCustomer在许多环境中是可互换的。这是因为这些语言允许用属性检查替换或补充类型标记检查。因此,如果您在JS、Ruby和&c.中调用x.foo(),它将在对象x上查找.foo属性。这允许消除一些类型标签检查,但通常不是全部。
注意,在带有结构类型的静态类型化语言中,可以让YourCustomer和MyCustomer在大多数/所有上下文中互换。这让一种语言感觉更接近像Javascript或Ruby这样的语言。我建议考虑一下TypeScript,它为Javascript添加了一个类型系统。
发布于 2016-01-10 01:26:36
当我们将一种语言描述为类型检查时,我们的意思是该语言不会让您执行对该类型无效的操作。无论是静态的还是动态的类型语言都不能让你把字符串相乘,用一个数字代替一个函数,等等。一种没有类型检查的语言可以让你在没有抱怨的情况下完成所有这些事情。
无论是在编译时检查所有类型,还是在运行时检查类型,还是查看对象是否响应消息,都是每种语言的实现细节。所有这些技术都属于类型检查的范畴。
发布于 2016-01-10 03:38:52
埃里克·利珀特 a型是
..。我们可以用规则来操纵的抽象数量。比如“如果
T是类型,那么T[]也是类型”,依此类推。
语言编译器或运行时实现类型的实现是另一回事。在编译语言(如C或C#或Java )中,这种检查是在编译时进行的,而在Java和C#中,这些检查也会在运行时进行。但是,在javascript和Ruby中,这些检查(据我所知)只在运行时进行,因为不需要编译。
那么,除了它是否响应特定的消息之外,您如何“检查”类型呢?
动态语言处理它所评估的每个表达式的类型,因为运行时需要知道它正在解释的对象的类型,以便知道要做什么!
在这里的另一个好答案中,给出了一些格式错误的表达式的例子,但也有一些其他的例子。例如,想想之间的区别==和===在javascript。
console.log('5' == 5) // true
console.log('5' === 5) // falsejavascript运行库需要在运行时检查对象的类型,以便遵守其规范。
https://softwareengineering.stackexchange.com/questions/307003
复制相似问题