1

我只是想弄清楚什么时候是一种已知是静态或动态类型的编程语言,或者同时被认为是静态类型和动态语言或动态类型和动态语言的概念。

我感到困惑的是,如果在 Java 的情况下变量的类型已知或在编译时定义时已知一种语言是静态类型的,即

//Java illustration of statically typed  
int x, y; //explicit type declaration 
x = 5, y = 10; //Now we use the variables 

//Groovy illustration of statically typed 
def x, y //explicit type declaration 
x = 1, y = 10 //now we use the variables

根据阅读各种在线资源,它说被认为是静态类型的语言列表不包括 Groovy,而是 Java 和 C++。

此外,如果 Groovy 是一种动态语言(DL 的定义 - DL 是一种在编译时进行很少或不进行检查的语言,而是在运行时进行检查)。这是否意味着 Groovy 也是一种动态类型语言,因为对于被认为是动态类型的变量“是在运行时而不是编译时知道变量的类型”。

//Illustration of a language being dynamically typed according to DT and DL definition
x = 5 //directly using the variable (exceptable in Python and PHP but not in Java/Groovy)

如果在 Groovy 中是这种情况,那么上述 Groovy 静态类型化的代码说明与 Groovy 在运行时完成的检查定义相矛盾。

这是否意味着 java groovy 都不是动态类型语言,因为直接使用变量会在 Java 和 groovy 中抛出编译器错误。

如果我错了,请纠正我。请提供带有代码说明的示例。

4

3 回答 3

1

我把它作为评论,但它被埋没了一点。

def 确实给出了一个类型,它使用“对象”的类型。就好像在 Java 中定义的每个变量都被定义为一个对象......(因此,Groovy 中的 def x=7 与 Java 中的 Object x=7 完全相同,没有更多或更少类型)。

这些对象总是以两种语言携带它们的类型信息。这两个也是等价的:

时髦的:
定义 x=5
断言(x == 5)
x="嘿,我换了类型!"
assert(x == "嘿,我换了类型!")

爪哇:
对象 x=5
断言(x == 5);
x="嘿,我——嗯,我有点改变了我的类型!"
assert(x.equals("嘿,我——我有点改变了我的类型!"))

最大的区别是Java强制(在编译时)你只调用它认为你拥有的类类型的已知方法。所以在上面的例子中,.toString() 和 .equals() 确实是唯一有用的方法. 要进行数学运算,您必须执行以下操作:

对象 x=5;
对象 y=7;
对象 z=(int)x + (int) y;
断言(z == 12);  
// 我相信 Integer z 会自动转
// 这里是一个int,但这可能无法编译:)

在 Groovy 中,该语言将简单地尝试调用该方法,并在运行时成功或失败。

这可以通过使用反射与 Java 进行模拟,您可以将所有内容都输入为“Object”(就像使用 groovy 的“def”一样)并编写一个反射实用程序来执行以下操作:

Object s="Hey, Wassup???";
对象 s2=magic(s, "toLowerCase")
断言(s2.equals(“嘿,wassup???”));

Groovy 只是隐藏了“魔法”。

所以我不认为你可以说一个本质上比另一个更具动态性,尽管你可能会说使用反射使两种语言都动态化,你也可以说 Groovy 使用反射比 java 多很多......

于 2013-01-25T21:44:09.897 回答
1

静态和动态类型主要是对变量(以及函数参数和返回值)的类型的描述。在许多静态类型语言中,您必须声明变量的类型,以便编译器知道哪些操作是有效的以及应该使用哪个重载版本的函数/操作符。一些现代静态类型语言(包括大多数函数式语言)具有类型推断功能,因此大多数时候您不必声明变量的类型。但是,变量仍必须具有固定类型。如果你将不同类型的值赋给同一个变量,编译器要么拒绝编译,要么只允许你做所有共同的操作。真正的强类型语言不能出现与类型相关的运行时故障。

在动态类型语言中,变量只是一个名称。您可以将任何类型的值分配给任何变量,并且可以通过分配不同类型的值来更改类型。只能在执行语句时检查函数调用或变量操作的有效性。(您可以将其视为将 Java 中的每个变量声明为 Object,并在使用时将它们转换为所需的类型。当然,编译器不会尝试确定转换是否成功,而是会插入可能导致运行失败的转换检查时间。)

动态语言通常意味着放宽编译器检查的大部分内容(语法可能是唯一事先检查的内容)。这通常意味着变量的存在甚至函数调用的有效性在必要时才被验证。他们通常使用动态类型,因为静态类型不利于放松。

于 2013-01-24T21:17:29.593 回答
0

请注意,在 Java 中,您必须告诉它变量的完整类型。'int' 在你的例子中。您可以说“float”或“Map”或“MyClassWithALongName”。

在 Groovy 中,您只是说 'def' 表示有一个变量,但您没有告诉它内容类型。

于 2013-01-24T20:35:54.843 回答