跟连乐一起学Scala-类型参数

欢迎加入Scala讨论QQ群212859367,和连乐一起讨论学习!



泛型类

例子:

class Pair[T, S](val first: T, val second: S)


泛型函数

例子:

def getMiddle[T](a: Array[T] = a(a.length / 2))

Scala会从调用该方法使用的实际参数来推断出类型。

getMiddle(Array("Mary", "had", "a", "little", "lamb"))
//将会调用getMiddle[String]


类型变量界定

解决问题:有时候,你需要对类型变量进行限制。

class Pair[T <: Comparable[T]](val first: T, val second: T) {
    def smaller = if (first.compareTo(second) < 0) first else second
}

以上示例中,T必须是Comparable[T]的子类型。



视图界定

示例:

class Pair[T <% Comparable[T]]

//意味着T可以被隐式转换成Comparable[T]


上下文界定

视图界定T<%V要求必须存在一个从T到V的隐式转换。

上下文界定的形式为:T:M,其中M是另一个泛型类,它要求必须存在一个类型为M[T]的“隐式值”。

例子:

class Pair[T : Ordering]
class Pair[T: Ordering](val first T, val second: T) {
    def smaller(implicit ord: Ordering[T]) =
        if (ord.compare(first, second) < 0) first else second
}

隐式值比隐式转换更灵活。



Manifest上下文界定

要实例化一个泛型的Array[T],我们需要一个Manifest[T]对象。

例子:

def makePair[T: Manifest](first: T, second: T) {
    val r = new Array[T](2)
    r(0) = first
    r(1) = second;
    r
}

如果你调用makePair(4, 9),编译器将定位到隐式的Manifest[Int]并实际上调用makePair(4,9)(intManifest),这样,该调用方法调用的就是new Array(2)(intManifest),返回基本类型的数组:int[2]



多重界定

类型变量可以同时有上界和下界:

T >: Lower <: Upper

你不能同时有多个上界或者多个下界。

你可以要求一个类型实现多个特质:

T <: Comparable[T] with Serializable with Cloneable

可以有多个视图界定,如下:

T <% Comparable[T] <% String

也可以有多个上下文界定,如下:

T : Ordering : Manifest


类型约束

T =:= U
T <:< U
T <%< U

上述约束将会测试T是否等于U,是否为U的子类,是否被视图(隐式)转换为U。

示例:

class Pair[T](val first: T, val second: T)(implicit ev: T <:<Comparable[T])

类型约束可以让你在泛型中定义只能在特定条件下使用的方法。

class Pair[T](val first: T, val second: T){
    def smaller(implicit ev: T <:< Ordered[T]) =
        if (first < second) first else second
}


型变

例子:

class Pair[+T] (val first: T, val second: T)

说明:加号意味着该类型是与T协变的,也就是说,它与T按同样的方向型变。

也可以有另一个方向的型变。

trait Friend[-T] {
    def befriend(someone: T)
}

在一个泛型的类型声明中,你可以同时使用这两种型变。



协变和逆变点

通常,对于某个对象消费的值适用逆变,而对于它产生的值则适用协变。



对象不能泛型

我们无法给对象添加类型参数。比如可变列表。



类型通配符

java中:

void makeFriends(Pair<? extends Person> people)

Scala中:

def process(people: java.util.List[_ <: Person])
def makeFriends(p: Pair[_ <: Person])

逆变的通配符使用:

import java.util.Comparator
def min[T] (p: Pair[T])(comp: Comparator[_ >: T])

欢迎加入Scala讨论QQ群212859367,和连乐一起讨论学习!

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-25 15:02:29

跟连乐一起学Scala-类型参数的相关文章

Scala类型参数中协变(+)、逆变(-)、类型上界(&lt;:)和类型下界(&gt;:)的使用

转自:http://fineqtbull.iteye.com/blog/477994#bc2364938 有位je上的同学来短信向我问起了Scala类型参数中协变.逆变.类型上界和类型下界的使用方法和原理,自己虽然也刚学不久,在主要调查了<Programing in Scala>的19章后,试着在下面做一个总结.如有错误之处还请各位指正. 先说说协变和逆变(实际上还有非变).协变和逆变主要是用来解决参数化类型的泛化问题.由于参数化类型的参数(参数类型)是可变的,当两个参数化类型的参数是继承关系

跟连乐一起学Scala-集合

欢迎加入Scala讨论QQ群212859367,和连乐一起讨论学习! 集合 主要的集合特质 Seq 是一 个有先后次序的值的序列.比如数组和列表.IndexedSeq允许我们通过整型的下标快速的访问任意元素. Set 是一组没有先后次序的值.在SortedSet中,元素以某种排过序的顺序被访问. Map 是一组(键,值)对偶.SortedMap按照键的排序访问其中的实体. 序列 Vector是ArrayBuffer的不可变版本:一个带下标的序列,支持快速的随机访问. 向量是以树形结构的形式实现的

快学Scala 第十九课 (trait的abstract override使用)

trait的abstract override使用: 当我看到abstract override介绍的时候也是一脸懵逼,因为快学scala,只介绍了因为TimestampLogger中调用的super.log依旧是个abstract class,所以必须在方法前加上abstract和override.但是并没有具体介绍如何使用,然后查阅了其他文档,才明白使用方法. 下面的代码定义了超类LoggerEmpty,这个定义意味着该特质只能混入扩展LoggerEmpty的类中. 在特质中声明抽象方法中有

快学Scala课后习题答案

分享一个之前做快学Scala的课后习题(2-21章节,19无)的Github链接,我把习题的文字写在了每个回答的注释上面,这样方便大家对照着看,省的回过头去对照着pdf看了,如果有做的不对的地方希望大家给予指正. 链接如下,http://github.com/fxxkinglife/scala-hello. 举一个第二章节的例子, object charpter02 { /* * 2.1 * 一个数字如果为正数,则它的signum为1; * 如果是负数,则signum为-1; * 如果为0,则s

大数据Spark蘑菇云前传第15课:Scala类型参数编程实战及Spark源码鉴赏(学习笔记)

前传第15课:Scala类型参数编程实战及Spark源码鉴赏 本課課程: Spark源码中的Scala类型系統的使用 Scala类型系統编程操作实战 Spark源码中的Scala类型系統的使用 classOf[RDD[_]] 這個也是类型系統 這里的意思是說 B 這種類型必需至少是 A 這樣類型 Ordering Scala类型系統编程操作实战 作為類型系統最大的就可以對類型進行限制,在Scala 中的類型系統,他本身也作為對象.e.g. 我們可以建立 Person 這個類,現在可以建立一個什麼

快学scala 第十一章 操作符 读书笔记及习题答案代码

chapter 11 操作符 标签:快学scala 一.笔记 scala种可以在反引号中包含几乎任何字符序列, val 'val' = 42 所有的操作符都是左结合的,除了以冒号(:)结尾的操作符,和赋值操作符.用于构造列表的::操作符是又结合的.1::2::Ni1的意思是1::(2::Ni1),先创建出包含2的列表,这个列表又被作为尾巴拼接到以1作为头部的列表中. 2. 函数调用语法:f(arg1, arg2,...)扩展到可以应用于函数之外的值,如果f不是函数或方法,那么这个表达式等于f.a

快学Scala习题解答—第一章 基础

1 简介 近期对Scala比较感兴趣,买了本<快学Scala>,感觉不错.比<Programming Scala:Tackle Multi-Core Complexity on the Java Virtual Machine>好很多. 是本不错的入门书.而且每个章节都设置了难度级别,每章有习题,可以巩固Scala语法. 本文的目的就是针对这些习题进行解答 2 基础 2.1 在Scala REPL中键入3,然后按Tab键.有哪些方法可以被应用? 这个....直接操作一遍就有结果了.

快学scala笔记.

第一章 基础 val 定义的值实际上是一个常量 var 声明其值可变的变量 val xmax,ymax = 100 var greeting,message: String = null 1.3 常用类型 Scala的7种数值类型:Byte.Char.Short.Int.Long.Float和Double 1.toString() 2.to(10) "Hello".intersect("World") 1.4 算术和操作符重载 val answer = 8 * 5

乐哥学AI_Python(二):Numpy索引,切片,常用函数

Numpy的索引和切片 ndarray对象的内容可以通过索引和切片查看和修改. 索引:ndarray对象中的元素索引基于0开始 切片:对数组里某个片段区域的描述 数组的切片也可以理解为原始数组的局部视图,都是指向内存中的原始数组,所以不同于列表复制,切片上的修改都会直接反映到原始数组上. 索引切片的实例代码演示: Numpy常用函数的代码演示: Numpy的置换函数transpose.T和swapaxes演示与区别 T适用于一.二维数组 arr = np.arange(12).reshape(3

从零学scala(九)类型参数、高级类型

一:类型参数 泛型类 //泛型类,基本和java是一致的          class Pair[T,S](val first:T,val second:S) val pair1 = new Pair("42",42)          val pair2 = new Pair[Any,Any](42,"42") 泛型函数 //返回数组中间的值          def getMiddle[T](a:Array[T]) = a(a.length/2) def mai