[英]What is this Scala syntax?
看看這個:
/** takes a Spellbook and returns a Spellbook guaranteeing
* that all spells have been loaded from the database. */
def checkIfSpellsLoaded[S <: Spellbook](spellbook :S) :Option[S { type SpellsLoaded }] =
if (spellbook.spellsLoaded) Some(spellbook.asInstanceOf[S { type SpellsLoaded }])
else None
def checkIfOwnerLoaded[S <: Spellbook](spellbook :S) :Option[S { type OwnerLoaded }] =
if (spellbook.ownerLoaded) Some(spellbook.asInstanceOf[S { type OwnerLoaded }])
else None
作為類型參數的一部分,{ type X } 在做什么? 這里發生了什么?
在 Scala class 中,成員可以是def
、 val
和(與我們相關的) type
https://docs.scala-lang.org/tour/abstract-type-members.html
https://typelevel.org/blog/2015/07/13/type-members-parameters.html
類型成員用於創建路徑相關類型
https://docs.scala-lang.org/scala3/book/types-dependent-function.html
如果Spellbook
有類型成員SpellsLoaded
, OwnerLoaded
trait Spellbook {
type SpellsLoaded
type OwnerLoaded
def spellsLoaded: Boolean
def ownerLoaded: Boolean
}
那么對於S <: Spellbook
Spellbook,類型S
、 S { type SpellsLoaded }
和S { type OwnerLoaded }
是相同的
type S <: Spellbook
implicitly[(S { type SpellsLoaded }) =:= S] // compiles
implicitly[S =:= (S { type SpellsLoaded })] // compiles
implicitly[(S { type OwnerLoaded }) =:= S] // compiles
implicitly[S =:= (S { type OwnerLoaded })] // compiles
但是如果Spellbook
沒有類型成員SpellsLoaded
, OwnerLoaded
trait Spellbook {
// no SpellsLoaded, OwnerLoaded
def spellsLoaded: Boolean
def ownerLoaded: Boolean
}
那么精化類型S { type SpellsLoaded }
和S { type OwnerLoaded }
只是S
的子類型(具有那些類型成員)
implicitly[(S { type SpellsLoaded }) <:< S] // compiles
// implicitly[S <:< (S { type SpellsLoaded })] // doesn't compile
implicitly[(S { type OwnerLoaded }) <:< S] // compiles
// implicitly[S <:< (S { type OwnerLoaded })] // doesn't compile
和精化類型S { type SpellsLoaded =... }
和S { type OwnerLoaded =... }
依次是前精化類型的子類型
implicitly[(S {type SpellsLoaded = String}) <:< (S {type SpellsLoaded})] // compiles
// implicitly[(S {type SpellsLoaded}) <:< (S {type SpellsLoaded = String})] // doesn't compile
implicitly[(S {type OwnerLoaded = Int}) <:< (S {type OwnerLoaded})] // compiles
// implicitly[(S {type OwnerLoaded}) <:< (S {type OwnerLoaded = Int})] // doesn't compile
S { type SpellsLoaded }
和S { type OwnerLoaded }
是S { type SpellsLoaded >: Nothing <: Any }
和S { type OwnerLoaded >: Nothing <: Any }
的縮寫,而S { type SpellsLoaded = SL }
和S { type OwnerLoaded = OL }
是S { type SpellsLoaded >: SL <: SL }
和S { type OwnerLoaded >: OL <: OL }
的簡寫。
鑄造.asInstanceOf[S { type SpellsLoaded }]
, .asInstanceOf[S { type OwnerLoaded }]
看起來像SpellsLoaded
, OwnerLoaded
用作幻影類型
https://books.underscore.io/shapeless-guide/shapeless-guide.html#sec:labelled-generic:type-tagging (5.2 類型標記和幻像類型)
因此,您似乎以將方法checkIfSpellsLoaded
、 checkIfOwnerLoaded
應用於S
的類型進行編碼。
也可以看看
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.