Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala类型重写_Scala - Fatal编程技术网

Scala类型重写

Scala类型重写,scala,Scala,在下面两个答案后编辑 我试图编译下面的Scala代码 abstract class C { type T <: C def x(other: T): (T, T) } class C1 extends C { override type T = C1 override def x(other: C1): (C1, C1) = (this, this) } def doSthg(cs1 : List[C]) { val e1 =

在下面两个答案后编辑 我试图编译下面的Scala代码

  abstract class C {
    type T <: C
    def x(other: T): (T, T)
  }

  class C1 extends C {
    override type T = C1
    override def x(other: C1): (C1, C1) = (this, this)
  }

  def doSthg(cs1 : List[C]) {
    val e1 = cs1(0)
    val e2 = cs1(1)

    e1.x(e2)
  }
有什么想法吗

基本上,我想定义一个像上面C这样的泛型类,并在子类(C1)上具有正确类型的方法

在soSthg中对C调用泛型方法之前,一切都很好

谢谢

新编辑部分

非常感谢您的回复。 查看下面的代码,我希望避免出现异常

  abstract class G[T](val t: T) {
    def ~(): G[T]
  }
  abstract class C[T](val g: List[G[T]]) {
    def x(other: C[T]): (C[T], C[T])
  }

  class G1(override val t: Boolean) extends G[Boolean](t){
    override def ~() = new G1(!t)
  }

  class C1(override val g: List[G1]) extends C[Boolean](g) {
    override def x(other: C[Boolean]): (C[Boolean], C[Boolean]) = {
      val go = other.g.map(e => e.asInstanceOf[G1])
      //val go = other.g
      val nc1 = new C1(go)
      (nc1, nc1) // for demo
    }
  }
x(其他:C[Boolean])的签名确实是个问题

这将有助于:

def doSthg2[T <: C](csl : List[T]) { csl(0).x(csl(1)) }

def doSthg2[T
C1
编译良好。请注意,您可以在此处删除
override
关键字:

class C1 extends C {
  type T = C1
  def x(other: C1): (C1, C1) = (this, this) // do you mean (other, this)?
}
doSthg
是无效的:您无法证明
e2
e1.t
。这与预期一样有效:

def doSthg(e1: C)(e2: e1.T) {
  e1.x(e2)
}
或者这个:

abstract class C {
  ...
  def create(): T
}

def doSthg(e1: C) {
  val e2 = e1.create()
  e1.x(e2)
}
对于原始
doSthg
方法
x
应接受
C
的任何实例:

trait C {
  def x(other: C): (C, C)
}

C1
编译良好。请注意,您可以在此处删除
override
关键字:

class C1 extends C {
  type T = C1
  def x(other: C1): (C1, C1) = (this, this) // do you mean (other, this)?
}
doSthg
是无效的:您无法证明
e2
e1.t
。这与预期一样有效:

def doSthg(e1: C)(e2: e1.T) {
  e1.x(e2)
}
或者这个:

abstract class C {
  ...
  def create(): T
}

def doSthg(e1: C) {
  val e2 = e1.create()
  e1.x(e2)
}
对于原始
doSthg
方法
x
应接受
C
的任何实例:

trait C {
  def x(other: C): (C, C)
}

如上所述定义C&C1没有问题。问题是您正在向e1.x传递类型为C(不是C1)的参数,因此违反了C1.x方法签名

就编译器而言:

  • 您正在建模一个以trait/class
    C
  • doSthg
    内部,vals
    e1
    e2
    都是层次结构中的某种类型。对于e1和e2,唯一可以确定的是
    e1.type
    e2.type
    都是
    C
    的子类型。不能保证
    e1
    e2
    是同一类型(或者是彼此的子类型)-即使类层次结构很浅(只有一个子类,
    C1
    )。您可以在将来的任何时候通过在新的.class/.jar文件中添加
    C
    的新子类型进行扩展(可能是由这台计算机上此编译器的.scala/.java文件生成的,甚至可能是由另一台计算机上的另一个编译器生成的!)

  • 您选择了您的方法
    C1.x
    不灵活-它的参数必须是
    C1
    类型,而不是任何
    C
    。因此,
    e1.x
    不能接受“任意”的
    e2如上所述定义C&C1没有问题。问题是您正在向e1.x传递一个类型为C(不是C1)的参数因此违反了C1.x方法签名

    就编译器而言:

  • 您正在建模一个以trait/class
    C
  • doSthg
    内部,vals
    e1
    e2
    都是层次结构中的某种类型。对于e1和e2,唯一可以确定的是
    e1.type
    e2.type
    都是
    C
    的子类型。不能保证
    e1
    e2
    是同一类型(或者是彼此的子类型)-即使类层次结构很浅(只有一个子类,
    C1
    )。您可以在将来的任何时候通过在新的.class/.jar文件中添加
    C
    的新子类型进行扩展(可能是由这台计算机上此编译器的.scala/.java文件生成的,甚至可能是由另一台计算机上的另一个编译器生成的!)

  • 您已经选择了您的方法
    C1.x
    不灵活-它的参数必须是
    C1
    类型,而不是任何
    C
    。因此,
    e1.x
    确实不能接受“任意”的
    e2。类似的方法可以工作:def doSthg2[T确实。类似的方法可以工作:def doSthg2[T]