Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.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_Structural Typing - Fatal编程技术网

Scala中的广义结构类型一致性

Scala中的广义结构类型一致性,scala,structural-typing,Scala,Structural Typing,我感兴趣的是如何将一种特定的结构类型与一种更一般的结构类型相一致。考虑下面的例子: trait Sup trait Sub extends Sup type General = { def contra(o: Sub): Unit def co(): Sup def defaults(age: Int): Unit def defaults2(age: Int): Unit def defaults3(first: String): Unit } trait

我感兴趣的是如何将一种特定的结构类型与一种更一般的结构类型相一致。考虑下面的例子:

trait Sup

trait Sub extends Sup

type General = {
   def contra(o: Sub): Unit
   def co(): Sup
   def defaults(age: Int): Unit
   def defaults2(age: Int): Unit
   def defaults3(first: String): Unit
} 

trait Specific {
   def contra(o: Sup): Unit // doesn't conform
   def co(): Sub // conforms
   def defaults(age: Int, name: String = ""): Unit // doesn't conform
   def defaults2(name: String = "", age: Int = 0): Unit // doesn't conform
   def defaults3(first: String = "", last: String = ""): Unit // doesn't conform
}
在每种不符合要求的情况下,调用
常规
中的方法可以安全地解析为
特定
中的相应方法。以下是一个更有趣的实例:

这里,客户的
copy
方法与Versionable的自类型注释中的签名不一致。但是,请注意,如果编译器允许,
copy
可以像在
Versionable.incrementVersion
中一样调用。显然,客户的
copy
方法的实际签名对于Versionable来说太具体了,因为它携带了不相关的知识,可以选择提供
名称
参数


有没有办法克服这些限制?有没有理由认为这种通用一致性是个坏主意?

一个问题是,当您阅读此代码时:

self: { def copy(version: Int): T }
您不希望参数的名称是重要的,因为在本例中必须是:

case class Robot(number: Int, override val version: Int)
  extends Versionable[Robot]
编辑:另一方面,关于方法缺少参数对冲,您可以:

type General = { val contra: (Sub => Unit) }
class B { val contra = ((o:Sup) => println(o)) }
var b:General = new B

这是一个很好的观点。无论如何,这种广义一致性不应该是默认的(出于性能原因)。我认为,在结构类型中的
版本
参数上需要
@命名
注释可以解决这两个问题。另一个实际示例:
type General = { val contra: (Sub => Unit) }
class B { val contra = ((o:Sup) => println(o)) }
var b:General = new B