假設我有以下操作,首先執行讀取操作,然后更新欄位。
action1: DBIOAction[Any, NoStream, Read with Write]
讓我們action2
對同一張表進行另一個讀取操作。要按順序執行這三個操作,我執行以下操作:
val action3 = action1 andThen action2
所以我認為輸出應該是格式。
action3: DBIOAction[Any, NoStream, Read with Write with Read]
但是當我看到輸出再次是這種形式時:
DBIOAction[Any, NoStream, Read with Write]
確實在我寫的方法簽名中, DBIOAction[Any, NoStream, Read with Write with Read]
但 IntelliJ 沒有抱怨。這似乎不正確。我做錯了嗎?
uj5u.com熱心網友回復:
Read with Write with Read
并且Read with Write
大多是同一型別:
implicitly[Read with Write with Read =:= Read with Write] // compiles
implicitly[Read with Write =:= Read with Write with Read] // compiles
implicitly[Write with Read =:= Read with Write] // compiles
implicitly[Read with Write =:= Write with Read] // compiles
盡管根據規范,它們似乎不等價(≡):
兩個復合型別是等價的,如果它們的組件的序列是成對等價的,并且以相同的順序出現,并且它們的細化是等價的。
查看編譯器:
https://github.com/scala/scala/pull/3981
RefinedType#normalize
負責將嵌套的復合型別展平為平面表示。
=:=
在搜索成功結果的程序中,型別被標準化。這意味著
((A with B) with C) =:= (A with B with C)
.
https://github.com/retronym/scala/blob/a9182fbeaf018c1aa0f88f0aee7b921383b746f2/src/reflect/scala/reflect/internal/Types.scala#L1601-L1619
private def normalizeImpl = {
// TODO see comments around def intersectionType and def merge
// SI-8575 The dealias is needed here to keep subtyping transitive, example in run/t8575b.scala
def flatten(tps: List[Type]): List[Type] = {
def dealiasRefinement(tp: Type) = if (tp.dealias.isInstanceOf[RefinedType]) tp.dealias else tp
tps map dealiasRefinement flatMap {
case RefinedType(parents, ds) if ds.isEmpty => flatten(parents)
case tp => List(tp)
}
}
val flattened = flatten(parents).distinct
if (decls.isEmpty && hasLength(flattened, 1)) {
flattened.head
} else if (flattened != parents) {
refinedType(flattened, if (typeSymbol eq NoSymbol) NoSymbol else typeSymbol.owner, decls, NoPosition)
} else if (isHigherKinded) {
etaExpand
} else super.normalize
}
flatten(...)
注意和的用法.distinct
。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/506749.html