多态Scala返回类型 [英] Polymorphic Scala return type

查看:144
本文介绍了多态Scala返回类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个抽象Scala类 Base ,它有子类 Derived1 Derived2 Base 定义了一个函数f(),它返回与其实现类相同类型的对象。因此 Derived1.f()返回 Derived1 Derived2.f()返回 Derived2 。我该如何在Scala中编写它?



这是我到目前为止所提供的。



<$ p $ > package com.github.wpm.cancan

抽象类Base [
def f [C< Base]:C
}

case class Derived1(x:Int)extends Base {
def f [Derived1] = Derived1(x + 1)
}

case class Derived2( x:Int)扩展Base {
def f [Derived2] = Derived2(x + 2)
}

这给出了下列编译器错误:

  type mismatch; 
[error] found:com.github.wpm.cancan.Derived1
[error] required:Derived1
[error] def f [Derived1] = Derived1(x + 1)

类型不匹配;
[error] found:com.github.wpm.cancan.Derived2
[error] required:Derived2
[error] def f [Derived2] = Derived2(x + 2)

这个错误信息令我感到困惑,因为我认为 com.github.wpm.cancan。在这种情况下,Derived1 应该与 Derived1 相同。

解决方案

Randall Schulz指出了你当前的代码不起作用的原因之一。尽管如此,可以通过 F - 有界多态性获得所需内容: p>

  trait Base [C<:Base [C]] {def f:C} 

案例类Derived1(x:Int)extends Base [Derived1] {
def f:Derived1 = Derived1(x + 1)
}

案例类Derived2(x:Int)extends Base [Derived2] {
//请注意,您不必在此处提供返回类型。
def f = Derived2(x + 2)
}

在基础特征允许你谈论那里的实现类 - 例如在 f


的返回类型中

I have an abstract Scala class Base which has subclasses Derived1 and Derived2. Base defines a function f() which returns an object of the same type as its implementing class. So Derived1.f() returns Derived1 and Derived2.f() returns Derived2. How do I write this in Scala?

Here is what I have come up with so far.

package com.github.wpm.cancan

abstract class Base {
  def f[C <: Base]: C
}

case class Derived1(x: Int) extends Base {
  def f[Derived1] = Derived1(x + 1)
}

case class Derived2(x: Int) extends Base {
  def f[Derived2] = Derived2(x + 2)
}

This gives the following compiler errors:

type mismatch;
[error]  found   : com.github.wpm.cancan.Derived1
[error]  required: Derived1
[error]   def f[Derived1] = Derived1(x + 1)

type mismatch;
[error]  found   : com.github.wpm.cancan.Derived2
[error]  required: Derived2
[error]   def f[Derived2] = Derived2(x + 2)

This error message is confusing to me because I think com.github.wpm.cancan.Derived1 should be the same as Derived1 in this context.

解决方案

Randall Schulz pointed out one of the reasons your current code doesn't work. It is possible to get what you want, though, with F-bounded polymorphism:

trait Base[C <: Base[C]] { def f: C }

case class Derived1(x: Int) extends Base[Derived1] {
  def f: Derived1 = Derived1(x + 1)
}

case class Derived2(x: Int) extends Base[Derived2] {
  // Note that you don't have to provide the return type here.
  def f = Derived2(x + 2)
}

The type parameter on the base trait allows you to talk about the implementing class there—e.g. in the return type for f.

这篇关于多态Scala返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆