# 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias

<div id="category"></div>

## 类型关联 Type Alias

### type关键字

scala里的类型，除了在定义class,trait,object时会产生类型，还可以通过type关键字来声明类型。

type相当于声明一个类型别名：

```object TestMatrix extends App{
type IntList = List[Int]
//接下来就可以这样使用它：
type Matrix = List[IntList]

val m = Matrix( IntList(1,2,3),
IntList(1,2,3),
IntList(1,2,3))
}```
```scala> type IntList=List[Int]
defined type alias IntList```

`type PersonPredicate = Person => Boolean`

`val teenagerPred: PersonPredicate = person => person.age < 20`

```  def teenagers(people: People): People = {
people.filter(teenagerPred)
}```

```  type Tax = Person => Double
val incomeTax: Tax = person => person.income * 5 / 100
val kejuanzaTax: Tax = person => person.income * 20 / 100
def giveMeYourMoney(p: Person) = {
calculateTax(p, List(incomeTax, kejuanzaTax))
}
def calculateTax(person: Person, taxes: List[Tax]): Double = {
taxes.foldLeft(0d) {
(acc, curTax) => acc + curTax(person)
}
}```

```  type twentyThree = (
String, String, String, String,
String, String, String, String,
String, String, String, String,
String, String, String, String,
String, String, String, String,
String, String, String
) => String```

Scala编译器会直接告诉我们： type Function23 is not a member of package scala

## 结构类型

```scala> def free( res: {def close():Unit} ) {
res.close
}

scala> free(new { def close()=println("closed") })
closed```

```scala> type X = { def close():Unit }
defined type alias X

scala> def free(res:X) = res.close

scala> free(new { def close()=println("closed") })
closed```

```scala> object A { def close() {println("A closed")} }

scala> free(A)
A closed

scala> class R { def close()=print("ok") }

scala> val r = new R

scala> free(r)
ok```

```scala> trait X1; trait X2;

scala> def test(x: X1 with X2 { def close():Unit } ) = x.close```

`X1 with X2 { def close():Unit }`

## 复合类型与with关键字

```class A extends (B with C with D with E)

T1 with T2 with T3 …```

```scala> trait X1; trait X2;

scala> def test(x: X1 with X2) = {println("ok")}
test: (x: X1 with X2)Unit

scala> test(new X1 with X2)
ok

scala> object A extends X1 with X2

scala> test(A)
ok```

```scala> type X = X1 with X2
defined type alias X

scala> def test(x:X) = println("OK")
test: (x: X)Unit

scala> class A extends X1 with X2

scala> val a = new A

scala> test(a)
OK```

## 结构类型

```    class Structural { def open()=print("A class instance Opened") }

object Structural__Type {

def main(args: Array[String]){
init(new { def open()=println("Opened") }) //创建了一个匿名对象，实现open方法
type X = { def open():Unit } //将右边的表达式命名为一个别名
def init(res:X) = res.open
init(new { def open()=println("Opened again") })

object A { def open() {println("A single object Opened")} } //创建的单例对象里面也必须实现open方法
init(A)

val structural = new Structural
init(structural)

}

def init( res: {def open():Unit} ) { //要求传进来的res对象具有open方法，不限制类型
res.open
}
}```

Scala复合类型解析：

```    trait Compound_Type1;
trait Compound_Type2;
class Compound_Type extends Compound_Type1 with Compound_Type2
object Compound_Type {
def compound_Type(x: Compound_Type1 with Compound_Type2) = {println("Compound Type in global method")} //限制参数x即是Type1的类型，也是Type2的类型
def main(args: Array[String]) {

compound_Type(new Compound_Type1 with Compound_Type2) //匿名方式，结果：Compound Type in global method
object compound_Type_oject extends Compound_Type1 with Compound_Type2 //object继承方式，trait混入object对象中
compound_Type(compound_Type_oject) //结果都一样，Compound Type in global method

type compound_Type_Alias = Compound_Type1 with Compound_Type2 //定义一个type别名
def compound_Type_Local(x:compound_Type_Alias) = println("Compound Type in local method") //使用type别名进行限制
val compound_Type_Class = new Compound_Type
compound_Type_Local(compound_Type_Class) //结果：Compound Type in local method

type Scala = Compound_Type1 with Compound_Type2 { def init():Unit } //type别名限制即是Type1，也是Type2，同时还要实现init方法
}

}```

## Infix Type

Infix Type：中值类型，允许带有两个参数的类型。

```    object Infix_Types {

def main(args: Array[String]) {

object Log { def >>:(data:String):Log.type = { println(data); Log } }

val list = List()
val newList = "A" :: "B" :: list //中值表达式
println(newList)

class Infix_Type[A,B] //中值类型是带有两个类型参数的类型
val infix: Int Infix_Type String = null //此时A是Int，B为String，具体类型名写在两个类型中间
val infix1: Infix_Type[Int, String] = null //和这种方式等价

case class Cons(first:String,second:String) //中值类型
val case_class = Cons("one", "two")
case_class match { case "one" Cons "two" => println("Spark!!!") } //unapply

}

}```

## self-type

```    class Self {
self => //self是this别名
val tmp="Scala"
def foo = self.tmp + this.tmp
}
trait S1
class S2 { this:S1 => } //限定：实例化S2时，必须混入S1类型
class S3 extends S2 with S1
class s4 {this:{def init():Unit} =>} //也能用于结构类型限定

trait T { this:S1 => } //也能用于trait
object S4 extends T with S1
object Self_Types {

def main(args: Array[String]) {
class Outer { outer =>
val v1 = "Spark"
class Inner {
println(outer.v1)  //使用外部类的属性
}
}
val c = new S2 with S1 //实例化S2时必须混入S1类型
}

}```
```---

---

<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="http://yandex.st/highlightjs/6.2/highlight.min.js"></script>

<script type="text/javascript">
\$("h2,h3,h4,h5,h6").each(function(i,item){
var tag = \$(item).get(0).localName;
\$(item).attr("id","wow"+i);
\$("#category").append('<a class="new'+tag+'" href="#wow'+i+'">'+\$(this).text()+'</a></br>');
\$(".newh2").css("margin-left",0);
\$(".newh3").css("margin-left",20);
\$(".newh4").css("margin-left",40);
\$(".newh5").css("margin-left",60);
\$(".newh6").css("margin-left",80);
});
});
</script>```

0 条评论

## 相关文章

1321

### 窥探Swift之字符串（String）

之前总结过Objective-C中的字符串《Objective-C精选字符串处理方法》，学习一门新语言怎么能少的了字符串呢。Swift中的String和Ob...

2356

### Kotlin学习之常用高阶函数：filter

Kotlin学习之常用高阶函数：filter Kotlin高阶函数一般是数组、集合、序列等数据结构的扩展函数，接收一个操作函数对数据进行操作，在Kotlin函数...

23510

2099

3286

751

### 【选择题】Java基础测试七

【选择题】Java基础测试七 86.欲构造ArrayList类的一个实例，此类继承了List接口，下列哪个方法是正确的？（ B ） A、ArrayList m...

6273

3076

### 05-02总结方法，数组（一维）

/* 练习题（1） 数组遍历：就是依次输出数组中的每一个元素。 注意：数组提供了一个属性length，用于获取数组的长度。 格式：数组名.lengt...

3597

### 7.哈希

哈希（Hash）又称散列，它是一个很常见的算法。在Java的HashMap数据结构中主要就利用了哈希。哈希算法包括了哈希函数和哈希表两部分。我们数组的特性可...

2609