Java 野生FJ论文中类型变量和类型参数之间的差异?

Java 野生FJ论文中类型变量和类型参数之间的差异?,java,generics,types,wildcard,type-parameter,Java,Generics,Types,Wildcard,Type Parameter,在Torgersen等人2005年的论文中,第2节和第3节的第一段使用了术语类型参数。然后,第3.1节的第一句话介绍了术语类型变量。考虑到讨论它的上下文以及谷歌缺乏相关信息,我只能猜测类型变量是专门用来指通配符的。我敢肯定,这是导致在Java中实现通配符的开创性论文 编辑:非常感谢Duplicater为编辑我的问题付出的辛勤工作 在fooint x方法中,使用以下术语: 该方法有1个形式参数intx,尽管它通常被缩短为参数,这可能导致混淆。int是参数类型,x是参数名称 x是一个参数变量,尽管它

在Torgersen等人2005年的论文中,第2节和第3节的第一段使用了术语类型参数。然后,第3.1节的第一句话介绍了术语类型变量。考虑到讨论它的上下文以及谷歌缺乏相关信息,我只能猜测类型变量是专门用来指通配符的。我敢肯定,这是导致在Java中实现通配符的开创性论文

编辑:非常感谢Duplicater为编辑我的问题付出的辛勤工作

在fooint x方法中,使用以下术语:

该方法有1个形式参数intx,尽管它通常被缩短为参数,这可能导致混淆。int是参数类型,x是参数名称

x是一个参数变量,尽管它经常被缩短为parameter,这会导致潜在的混淆

在调用foo5中,该值称为参数,但通常称为参数值,缩写为parameter,这可能会导致混淆。当需要澄清时,它被称为实际参数

如您所见,单词parameter的简写用法可以表示int x、x或5,具体取决于上下文

对于泛型类型Foo,使用类似的命名:

该类型有1个类型参数,其中extends Number是类型绑定,X是类型标识符

X是一个类型变量

使用Foo时,整数部分称为类型参数。类型参数可以是通配符

不要混淆方法参数类型和泛型类型参数

正如您所看到的,您认为类型变量用于具体引用通配符的结论是不正确的。类型变量引用类型参数名称,而不管类型参数是否绑定

类型变量的实际类型(即类型参数)可能是通配符,也可能不是,因为它是在泛型类型的使用中指定的,而不是在泛型类型的定义中指定的

泛型类型变量仅在泛型类型的定义中引用,类似于方法参数变量仅在方法体中引用的方式。

在方法fooint x中,使用以下术语:

该方法有1个形式参数intx,尽管它通常被缩短为参数,这可能导致混淆。int是参数类型,x是参数名称

x是一个参数变量,尽管它经常被缩短为parameter,这会导致潜在的混淆

在调用foo5中,该值称为参数,但通常称为参数值,缩写为parameter,这可能会导致混淆。当需要澄清时,它被称为实际参数

如您所见,单词parameter的简写用法可以表示int x、x或5,具体取决于上下文

对于泛型类型Foo,使用类似的命名:

该类型有1个类型参数,其中extends Number是类型绑定,X是类型标识符

X是一个类型变量

使用Foo时,整数部分称为类型参数。类型参数可以是通配符

不要混淆方法参数类型和泛型类型参数

正如您所看到的,您认为类型变量用于具体引用通配符的结论是不正确的。类型变量引用类型参数名称,而不管类型参数是否绑定

类型变量的实际类型(即类型参数)可能是通配符,也可能不是,因为它是在泛型类型的使用中指定的,而不是在泛型类型的定义中指定的


泛型类型变量仅在泛型类型的定义中引用,类似于方法参数变量仅在方法体中引用的方式。

全文搜索显示该类型变量首先出现在第2节:

只要元素类型在调用站点是已知的,就可以使用带有伪类型变量的非对称方法用普通泛型表示:

〈X〉void m1(List〈X〉list) { ... }
正如您所看到的,这个示例根本不使用通配符,这与您的假设相矛盾,即类型变量用于专门引用通配符

那么,什么是类型变量?由于该术语未在本文中定义,因此必须在其参考文献中定义

但是哪一个呢?由于习惯上在首次使用术语之前包括引用,因此引用必须在引言部分,从上下文来看,这句话看起来最有希望:

参数多态性——也称为泛型或泛型——起源于函数编程领域[21]

因此,我们很可能从中找到答案

[21]罗宾·米尔纳。编程中的类型多态理论。《计算机与系统科学杂志》,17:348–375,8月19日 78

通过谷歌搜索该论文的标题,会发现一个包含全文的PDF,事实上,该经典论文包含了许多类型变量的示例,例如:

例1

将函数映射到列表上

let rec map(f, m) = if null (m) then nil 
                    else cons (f(hd(m)), map (f, d(m)))
直观地说,这样声明的函数映射将函数从一种类型的事物转换为另一种类型的事物,并生成第一种类型的事物列表,然后生成第二种类型的事物列表。所以我们说map有类型

α&向右箭头;βxα列表&右箭头;β表

其中α、β为类型变量

因此,类型变量只是一个数学意义上的变量,它将包含一个类型。类型变量可以通过类型参数引入,但正如米尔纳所示,类型变量也可以通过其他方式引入。注意α和β是如何在map的定义中不出现的

Java编译器执行通配符捕获时也会发生类似的情况。例如,如果我们写:

List<?> sourceList = ...;
List<?> targetList = ...;
targetList.add(sourceList.get(0));
编者说:

The method add(capture#1-of ?) in the type List<capture#1-of ?> is not applicable for the arguments (capture#2-of ?)
如我们所见,在对通配符类型进行推理时,编译器将通配符的值捕获到新的类型变量中,例如capture1 of?。与类型参数引入的类型变量不同,这些类型变量永远不会出现在源代码中


这就是为什么在讨论通配符捕获时,Wild FJ论文谈到了类型参数未引入的类型变量。

全文搜索显示类型变量首先出现在第2节:

只要元素类型在调用站点是已知的,就可以使用带有伪类型变量的非对称方法用普通泛型表示:

〈X〉void m1(List〈X〉list) { ... }
正如您所看到的,这个示例根本不使用通配符,这与您的假设相矛盾,即类型变量用于专门引用通配符

那么,什么是类型变量?由于该术语未在本文中定义,因此必须在其参考文献中定义

但是哪一个呢?由于习惯上在首次使用术语之前包括引用,因此引用必须在引言部分,从上下文来看,这句话看起来最有希望:

参数多态性——也称为泛型或泛型——起源于函数编程领域[21]

因此,我们很可能从中找到答案

[21]罗宾·米尔纳。编程中的类型多态理论。《计算机与系统科学杂志》,17:348-375,1978年8月

通过谷歌搜索该论文的标题,会发现一个包含全文的PDF,事实上,该经典论文包含了许多类型变量的示例,例如:

例1

将函数映射到列表上

let rec map(f, m) = if null (m) then nil 
                    else cons (f(hd(m)), map (f, d(m)))
直观地说,这样声明的函数映射将函数从一种类型的事物转换为另一种类型的事物,并生成第一种类型的事物列表,然后生成第二种类型的事物列表。所以我们说map有类型

α&向右箭头;βxα列表&右箭头;β表

其中α、β为类型变量

因此,类型变量只是一个数学意义上的变量,它将包含一个类型。类型变量可以通过类型参数引入,但正如米尔纳所示,类型变量也可以通过其他方式引入。注意α和β是如何在map的定义中不出现的

Java编译器执行通配符捕获时也会发生类似的情况。例如,如果我们写:

List<?> sourceList = ...;
List<?> targetList = ...;
targetList.add(sourceList.get(0));
编者说:

The method add(capture#1-of ?) in the type List<capture#1-of ?> is not applicable for the arguments (capture#2-of ?)
如我们所见,在对通配符类型进行推理时,编译器将通配符的值捕获到新的类型变量中,例如capture1 of?。与类型参数引入的类型变量不同,这些类型变量永远不会出现在源代码中


这就是为什么在讨论通配符捕获时,Wild FJ论文谈到了类型参数没有引入的类型变量。

类型变量,例如capture1 of?-capture1 of?不是类型变量。它是类型参数的匿名描述。在Java的运行时库中,接口定义了一个名为E的类型变量。在这个答案顶部引用的代码中,定义了一个名为X的类型变量,列表中的X是一个类型参数。在答案末尾的代码中,两个?是通配符类型的参数。@Andreas:在OP询问的论文中,通配符捕获被描述为引入新的类型变量,具体来说,他们写道:Java编程语言的类型系统采用了一种更激进的方法,称为“捕获转换”。上面的“开放”过程应用于每个表达式。新类型变量是全局可访问的。。。。这非常清楚地表明捕获转换确实创建了类型变量,不是吗?至于你其余的评论,我都知道,但我看不出它与OPs问题有什么关系?我同意,我也看不出你问题的最后一部分如何适用于这个问题,因为最后一部分只显示类型参数,而这个问题是关于
n类型参数和类型变量。错误基本上只是说,当应用于add方法时,sourceList的type参数与targetList的type参数不兼容。那与问题无关。捕获者1?你的第二个目标是什么?是类型变量的值,如编译器所示。它们本身不是类型变量。与方法类似,其中0是索引参数变量的值,对于泛型?是E type参数的值,编译器在其中命名?作为第1条的捕获者?为了确认身份,我似乎没有清楚地表达自己。OP对Wild FJ论文第3.1节中类型变量的含义感到困惑。该部分描述了通配符捕获。这就是为什么我要包含一个通配符捕获的示例,并将通配符捕获引入的类型变量与声明类型参数引入的类型变量进行对比。类型变量,例如capture1 of?-capture1 of?不是类型变量。它是类型参数的匿名描述。在Java的运行时库中,接口定义了一个名为E的类型变量。在这个答案顶部引用的代码中,定义了一个名为X的类型变量,列表中的X是一个类型参数。在答案末尾的代码中,两个?是通配符类型的参数。@Andreas:在OP询问的论文中,通配符捕获被描述为引入新的类型变量,具体来说,他们写道:Java编程语言的类型系统采用了一种更激进的方法,称为“捕获转换”。上面的“开放”过程应用于每个表达式。新类型变量是全局可访问的。。。。这非常清楚地表明捕获转换确实创建了类型变量,不是吗?至于你其余的评论,我都知道,但我看不出它与OPs问题有什么关系?我同意,我也看不出你问题的最后一部分是如何应用于这个问题的,因为最后一部分只显示类型参数,问题是关于类型参数和类型变量之间的区别。错误基本上只是说,当应用于add方法时,sourceList的type参数与targetList的type参数不兼容。那与问题无关。捕获者1?你的第二个目标是什么?是类型变量的值,如编译器所示。它们本身不是类型变量。与方法类似,其中0是索引参数变量的值,对于泛型?是E type参数的值,编译器在其中命名?作为第1条的捕获者?为了确认身份,我似乎没有清楚地表达自己。OP对Wild FJ论文第3.1节中类型变量的含义感到困惑。该部分描述了通配符捕获。这就是为什么我要举例说明什么是通配符捕获,并将通配符捕获引入的类型变量与声明类型参数引入的类型变量进行对比,Box@MatthewS. 它所说的对我来说毫无意义,这是错误的。根据标准规则,box.get的类型因此是Y是错误的,因为box.get的类型是T,因为没有Y。-即使有Y,它也不是类型变量,因为X是泛型类型box的唯一类型变量。Y是编译器看到的X的值。Java SE的作者在第4.5.1节末尾对本文进行了详细的介绍。甚至不是开玩笑,它在报纸的第3.1节中有很好的印刷,Box@MatthewS. 它所说的对我来说毫无意义,这是错误的。根据标准规则,box.get的类型因此是Y是错误的,因为box.get的类型是T,因为没有Y。-即使有Y,它也不是类型变量,因为X是泛型类型box的唯一类型变量。Y是编译器看到的X的值。Java SE的作者在第4.5.1节末尾对本文进行了详细的介绍。别开玩笑了,这是精美的印刷品