dotty编译器语法特性之一交叉类型,联合类型和文本单例类型
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
###翻譯:http://dotty.epfl.ch/docs/reference/intersection-types.html #交叉類型
trait Resettable {def reset(): this.type } trait Growable[T] {def add(x: T): this.type } def f(x: Resettable & Growable[String]) = {x.reset()x.add("first") }這里x要求必須是Resettable類型和Growable[T]類型,交叉類型A & B 替代了scala2中的復(fù)合類型A with B(目前,這種復(fù)合類型仍然可以使用,但是未來會被廢除)
與 with 復(fù)合類型不同,& 交叉類型是可互換的,比如:A & B和B & A是相同的類型。 一個(gè)交叉類型A & B的所有成員,是類型A的所有成員和類型B的所有成員之和。
例如Resettable & Growable[String]類型擁有reset和add兩個(gè)分別來自兩個(gè)類型的成員方法。
如果一個(gè)成員既出現(xiàn)在A類型中,又出現(xiàn)在B類型中,那么這個(gè)成員的類型在類型A & B中表現(xiàn)為A類型和B類型交叉。比如下面的例子:
trait A {def children: List[A]def say:Int = 1 } trait B {def children: List[B]def say:String = "2" } class C extends A with B {def children: List[A & B] = List(new C)override def say:Int & String = super.say + 3} val x: A & B = new C val xs: List[A] & List[B] = x.children val ys: List[A & B] = x.children這個(gè)成員children 在 A & B的類型,是 children在A中的類型List[A]和children在B中類型List[B]的交叉類型List[A] & List[B] 。這個(gè)能進(jìn)一步簡化為List[A & B] ,因?yàn)長ist是協(xié)變的。
聯(lián)合類型
翻譯:http://dotty.epfl.ch/docs/reference/union-types.html
操作符|創(chuàng)建一個(gè)聯(lián)合類型
case class UserName(name: String) {def lookup(admin: Admin): UserData } case class Password(hash: Hash) {def lookup(admin: Admin): UserData }def help(id: UserName | PassWord) = {val user = id match {case UserName(name) => lookupName(name)case Password(hash) => lookupPassword(hash)}// ... }聯(lián)合類型是雙重交叉類型。聯(lián)合類型A|B的值是所有A的值和所有B的值之和。 | 聯(lián)合類型是可互換的,比如:A | B和B | A是相同的類型。
只有當(dāng)一個(gè)表達(dá)式明確給出類型的時(shí)候,編譯器才會給這個(gè)表達(dá)式賦值一個(gè)聯(lián)合類型,例如:
scala> val password = Password(123) val password: Password = Password(123) scala> val name = UserName("Eve") val name: UserName = UserName(Eve) scala> if (true) name else password val res2: Object & Product = UserName(Eve) scala> val either: Password | UserName = if (true) name else password val either: Password | UserName = UserName(Eve) scala>help(either)res2的類型是Object & Product,它是 UserName 和 Product的一個(gè)超類,但不是類型的最小超類Password | UserName。如果想獲得最小超類,必須明確給出類型定義,就像這里的val either: Password | UserName的類型。要調(diào)用聯(lián)合類型的成員,使用類型匹配match,比如這里的help方法
#文本單例類型 看以下例子:
object Literals{val fortyTwo: 42 = 42val `2`: 2 = 2val fortyFour: 44 = fortyTwo + `2`val text: "text" = "text"def id[T](a: T) = aval two: 2 = id(`2`)final val T = 1 val x: T.type = 2 // error , 2 should be 1 }這里 val x: T.type = 2 會報(bào)錯(cuò),因?yàn)門.type文本類型只能賦值為原本定義的值,這里是1。這里的final val定義個(gè)值不可變的單例文本類型,使用T.type來引用,且只能賦值為原值。
轉(zhuǎn)載于:https://my.oschina.net/jackywyz/blog/913099
總結(jié)
以上是生活随笔為你收集整理的dotty编译器语法特性之一交叉类型,联合类型和文本单例类型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql为什么使用b 树作为索引_为什
- 下一篇: python输入法引擎_Bigram-M