gpt4 book ai didi

generics - 使用泛型和协方差进行 Scala 类型推断,scalac 中可能存在的问题

转载 作者:行者123 更新时间:2023-12-02 22:11:03 24 4
gpt4 key购买 nike

我列出了今天发现的问题的简短列表。我是 scala 新手,因此我的问题可能很微不足道。

假设我们有一个这样的类:

abstract class A[+T] { def foo[S >: T](x: S): String }

我们应该提供具有一些功能的有用子类。

1)我的第一次尝试如下所示:

class B extends A[String] { def foo(x: String) = x }

但是 scalac 编译器不同意消息:

xxx@yyy:~$ scalac covariant.scala 
covariant.scala:3: error: class B needs to be abstract, since method foo in class A of type [S >: String](x: S)String is not defined
class B extends A[String] { def foo(x: String) = x }
^

首先,为什么 scalac 没有推断 foo 的泛型类型参数,这真的是一个复杂的任务吗?

2)下一次尝试看起来更好,应该被接受,正如我认为的:

class B extends A[String] { def foo[String](x: String) = x }

但是现在编译器让我睁大了眼睛:

covariant.scala:3: error: type mismatch;
found : String(in method foo)
required: java.lang.String
class B extends A[String] { def foo[String](x: String) = x }
^

这看起来像是 String 和 java.lang.String 不匹配的问题。这是第二个问题:这真的是一个错误吗?

3)最后我决定将 String 类型切换为 Date 作为参数:

import java.util.Date
class B extends A[Date] { def foo[Date](x: Date) = x.toString }

它已编译,没有任何警告。所以最后一个问题是:为什么?我的第二个和第三个片段有什么区别?

顺便说一句,scalac版本是2.9.1.final

最佳答案

真的,你所有的问题都源于同一个误解。

您将其定义为“具有类型参数和方法 foo 的类,该类可以作用于 T 派生的任何 派生类型

您提供了一个带有 foo 的类,它可以作用于 T,但不能 必然 作用于 后代(实际上,由于参数是协变的,foo 实际上可以作用于后代,但规范不是足够紧以捕捉到) T 的父类(super class)。

在另外两个问题中,您不小心重复使用了现有类型的名称。当您编写 foo[Date] 或 foo[String] 时,您并不是像您所想的那样,指的是 java.lang.String 或 java.lang.Date,而是指的是同名的新类型!这就是为什么您会看到 String 和 java.lang.String 不匹配的原因——它们是两种不同的类型。

试试这个:

abstract class A[+T] { def foo[S >: T](x: S): String }
class B extends A[String] { def foo[S >: String](x: S) = x.toString }

是的, S >: String 是毫无意义的,因为 String 是最终的,但规范无法排除所有可能的边缘情况。

注意我也是个新手,所以如果我的答案是错误/误导性的,请不要感到震惊。请记住:此建议的值(value)保证是您所支付费用的两倍,或者您的钱会愉快地退还。

告诉你大错误:我颠倒了父类(super class)和子类。与 删除 内联进行的更正。

一个例子OP不清楚为什么这一切都是必要的。考虑以下函数

def foo3(a : A[String]) = a.foo(3)

这是合法的,因为 3(作为 java.lang.Integer)是一个对象的示例,它是 A 的祖先。如果 B.foo 被定义为采用 String 而没有其他,则不能是 B 的实例传递到 foo3 中。

关于generics - 使用泛型和协方差进行 Scala 类型推断,scalac 中可能存在的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8582586/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com