加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala中不同类型的路径依赖类型的特征

发布时间:2020-12-16 18:46:48 所属栏目:安全 来源:网络整理
导读:假设有一个特征: trait OuterTrait { type InnerType} 现在我们可以写一些非泛型函数someAlgo: def pairToString[S,U](x: S,y: U): String = "{" + y.toString + " in " + x.toString + "}"def pairPrintln[S,y: U) { println(pairToString(x,y))}def some
假设有一个特征:

trait OuterTrait {
  type InnerType
}

现在我们可以写一些非泛型函数someAlgo:

def pairToString[S,U](x: S,y: U): String = 
  "{" + y.toString + " in " + x.toString + "}"

def pairPrintln[S,y: U) {
  println(pairToString(x,y))
}

def someAlgo(x: OuterTrait)(y: x.InnerType): x.InnerType = {
  pairPrintln(x,y)
  y
}

和一系列通用功能:

def someAlgoObjObj[T <: OuterTrait](x: T)(y: x.InnerType): x.InnerType = {
  pairPrintln(x,y)
  y
}

def someAlgoObjType[T <: OuterTrait](x: T)(y: x.InnerType): T#InnerType = {
  pairPrintln(x,y)
  y
}

def someAlgoTypeType[T <: OuterTrait](x: T)(y: T#InnerType): T#InnerType = {
  pairPrintln(x,y)
  y
}

而另一个通用函数不编译:

def someAlgoTypeObj[T <: OuterTrait](x: T)(y: T#InnerType): x.InnerType = {
  pairPrintln(x,y)
  y
}

看起来:
1)someAlgo和someAlgoObjObj是最正确的函数;
2)在这个例子中根本没有使用泛型函数的意义.

我想澄清上面的通用函数之间的一些差异.请纠正我,如果我犯了错误.

因此,据我所知,类型T对应于静态类型的x(称为X)或显式类型的通用调用(我的意思是algo [Int]).这就是T#InnerType对应于X类型声明中的类型的原因.但x.InnerType也对应于静态类型x的InnerType.区别在哪里?

进一步… someAlgoObjType编译,因此似乎x.InnerType必须是T#InnerType的子类型.然后,someAlgoTypeObj无法编译,因为我们无法隐式地进行向下转换.虽然我们可以改写最后一个:

def someAlgoTypeObj[T <: OuterTrait](x: T)(y: T#InnerType): x.InnerType = {
  pairPrintln(x,y)
  y.asInstanceOf[x.InnerType]
}

UPD1:我发现someAlgoObjObj和someAlgoTypeType之间存在一个区别,如果将它们与显式类型参数一起使用.如果我们编写一些扩展OuterTrait的类:

class OuterIntClass extends OuterTrait{
  type InnerType = Int
}
val x: OuterIntClass = new OuterIntClass()
val y: Int = 5

然后:

someAlgoObjObj[OuterTrait](x)(y) // OK

和下一个电话不起作用:

someAlgoTypeType[OuterTrait](x)(y)

解决方法

T#InnerType表示“属于某些T的内部类型”,而x.InnerType表示“属于给定x(类型为OuterTrait)的内部类型”.

理解这些的关键在于给定x中的一些T vs.你可以将某些解释为某些T但我们没有哪个T实例,这意味着在两个Ts中不一定相同,因此,T#InnerType不能被证明等于另一个T#InnerType.

我们来分析一下签名:

/* 1 */ def someAlgoObjObj[T <: OuterTrait](x: T)(y: x.InnerType): x.InnerType = ???
/* 2 */ def someAlgoObjType[T <: OuterTrait](x: T)(y: x.InnerType): T#InnerType = ???
/* 3 */ def someAlgoTypeType[T <: OuterTrait](x: T)(y: T#InnerType): T#InnerType = ???

>给定x和属于此x的InnerType返回其InnerType.
>给定x和属于此x的InnerType返回属于某个T的InnerType,意味着某个T不一定是与x相同的实例.
>给定属于某些T的x和InnerType返回属于某些T的InnerType

现在为第四个:

def someAlgoTypeObj[T <: OuterTrait](x: T)(y: T#InnerType): x.InnerType = y

签名读取:给定属于某些T的x和InnerType,返回属于此x的InnerType.但是在实现中,我们尝试返回y,它属于一个不一定与x相同的T,因此编译器会抱怨.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读