spark基础-scala学习(七类型参数)(代码片段)

sky-chen sky-chen     2023-02-04     362

关键词:

类型参数是什么

  1. 类似于java泛型,泛型类
  2. 泛型函数
  3. 上边界Bounds
  4. 下边界
  5. View Bounds
  6. Context Bounds
  7. Manifest Context Bounds
  8. 协变和逆变
  9. Existential Type

泛型类

scala> :paste
// Entering paste mode (ctrl-D to finish)

class Student[T](val localId:T)
 def getSchoolId(hukouId:T) = "S-"+hukouId+"-"+localId


// Exiting paste mode, now interpreting.

defined class Student

scala> val s = new Student[Int](11)
s: Student[Int] = [email protected]

scala> s.getSchoolId(234)
res1: String = S-234-11

泛型函数

  1. 泛型函数,与泛型类类似,可以给某个函数在声明时指定泛型类型,然后在函数体内,多个变量或者返回值之间,就可以使用泛型类型进行声明,从而对某个特殊的变量,或者多个变量,进行强制性的类型限制
  2. 与泛型类一样,你可以通过使用了泛型类型的变量传递值来让Scala自动推断泛型的实际类型,也可以在调用函数时,手动指定泛型类型
scala> :paste
// Entering paste mode (ctrl-D to finish)

def getCard[T](content:T)=
 if(content.isInstanceOf[Int]) "card: 001,"+content
 else if(content.isInstanceOf[String]) "card:this is your card, "+content
 else "card: "+content


// Exiting paste mode, now interpreting.

getCard: [T](content: T)String

scala> getCard[String]("leo")
res2: String = card:this is your card, leo

scala> getCard[Int](123)
res3: String = card: 001,123

上边界Bounds

  1. 在指定泛型类型的时候,有时,我们需要对泛型类型的范围进行界定,而不是可以是任意的类型。比如,我们可能要求某个泛型类型,他就必须是某个类的子类,这样在程序中就可以放心地调用泛型类型继承的父类的方法,程序才能正常的使用和运行。此时就可以使用上下边界Bounds的特性
  2. scala的上下边界特性允许泛型类型必须是某个类的子类,或者必须是某个类的父类
scala> :paste
// Entering paste mode (ctrl-D to finish)

class Person(val name:String)
 def sayHello = println("Hello,I‘m "+name)
 def makeFriends(p:Person)
  sayHello
  p.sayHello
 

class Student(name:String) extends Person(name)
class Party[T <: Person](p1:T,p2:T)
 def play = p1.makeFriends(p2)


// Exiting paste mode, now interpreting.

defined class Person
defined class Student
defined class Party

scala> val p = new Person("Tom")
p: Person = [email protected]

scala> val p2 = new Person("leo")
p2: Person = [email protected]

scala> p.makeFriends(p2)
Hello,I‘m Tom
Hello,I‘m leo

scala> val s1 = new Student("Jarry")
s1: Student = [email protected]

scala> val s2 = new Student("Marry")
s2: Student = [email protected]

scala> val pa = new Party[Student](s1,s2)
pa: Party[Student] = [email protected]

scala> pa.play
Hello,I‘m Jarry
Hello,I‘m Marry

下边界Bounds

  1. 除了指定泛型类型的上边界,还可以指定下边界,即指定泛型类型必须是某个类的父类
scala> :paste
// Entering paste mode (ctrl-D to finish)

class Father(val name:String)
class Child(name:String) extends Father(name)

def getIDCard[R >: Child](person:R)
 if(person.getClass == classOf[Child]) println("please tell us your parents‘ names.")
  else if(person.getClass == classOf[Father]) println("sign your name for your child‘s id card.")
  else println("sorry,you are not allowed to get id card.")


// Exiting paste mode, now interpreting.

defined class Father
defined class Child
getIDCard: [R >: Child](person: R)Unit

scala> val f = new Father("fa")
f: Father = [email protected]

scala> val c = new Child("cd")
c: Child = [email protected]

scala> getIDCard[Father](f)
sign your name for your child‘s id card.

scala> getIDCard[Child](c)
please tell us your parents‘ names.

View Bounds

  1. 上下边界Bounds,虽然可以让一种泛型类型,支持有父子关系的多种类型。但是,在某个类与上下边界Bounds指定的父子类型范围内的类都没有任何关系,则默认是肯定不能接受的
  2. 然而,View Bounds作为一种上下边界Bounds的加强版,支持可以对类型进行隐式转换,将指定的类型进行隐式转换后,再判断是否在边界指定的类型范围内
  3. 案例:跟小狗交朋友
scala> :paste
// Entering paste mode (ctrl-D to finish)

class Person(val name:String)
 def sayHello = println("Hello,I‘m "+name)
 def makeFriends(p:Person)
  sayHello
  p.sayHello
 

class Student(name:String) extends Person(name)
class Dog(val name:String)def sayHello = println("Wang,Wang,I‘m "+name)

implicit def dog2person(dog: Object):Person = if(dog.isInstanceOf[Dog])val _dog = dog.asInstanceOf[Dog];new Person(_dog.name) else Nil
class Party[T <% Person](p1:T,p2:T)

// Exiting paste mode, now interpreting.

<pastie>:23: warning: implicit conversion method dog2person should be enabled
by making the implicit value scala.language.implicitConversions visible.
This can be achieved by adding the import clause ‘import scala.language.implicitConversions‘
or by setting the compiler option -language:implicitConversions.
See the Scaladoc for value scala.language.implicitConversions for a discussion
why the feature should be explicitly enabled.
implicit def dog2person(dog: Object):Person = if(dog.isInstanceOf[Dog])val _dog = dog.asInstanceOf[Dog];new Person(_dog.name) else Nil
             ^
defined class Person
defined class Student
defined class Dog
dog2person: (dog: Object)Person
defined class Party

scala> val leo = new Student("leo")
leo: Student = [email protected]

scala> val doggy = new Dog("doggy")
doggy: Dog = [email protected]

scala> val party = new Party(leo,doggy)
party: Party[Object] = [email protected]

Context Bounds

  1. Context Bounds是一种特殊的Bounds,它会根据泛型类型的声明,比如“T:类型”要求必须存在一个类型为“类型[T]”的隐式值。其实个人认为,Context Bounds之所以叫做Context,是因为它基于的是一种全局的上下文,需要使用到上下文中的隐式值以及注入
  2. 案例:使用Scala内置的比较器比较大小
scala> :paste
// Entering paste mode (ctrl-D to finish)

class Calculator[T:Ordering](val number1:T,val number2:T)
  def max(implicit order:Ordering[T]) = if(order.compare(number1,number2)>0)number1 else number2


// Exiting paste mode, now interpreting.

defined class Calculator

scala> val ca = new Calculator[Int](12,23)
ca: Calculator[Int] = [email protected]

scala> ca.max
res8: Int = 23

Manifest Context Bounds

  1. 在scala中,如果要实例化一个泛型数组,就必须使用Manifest Context Bounds,也就是说,如果数组元素类型为T的话,需要为类或者函数定义[T:Manifest]泛型类型,这样才能实例化Array[T]这种泛型数组
  2. 案例:打包饭菜(一种食品打成一包)
scala> :paste
// Entering paste mode (ctrl-D to finish)

class Meat(val name:String)
class Vegetable(val name:String)

def packageFood[T:Manifest](food: T*) = 
 val foodPackage = new Array[T](food.length)
 for(i <- 0 until food.length) foodPackage(i) = food(i)
 foodPackage


// Exiting paste mode, now interpreting.

defined class Meat
defined class Vegetable
packageFood: [T](food: T*)(implicit evidence$1: Manifest[T])Array[T]

scala> val gongbaojiding = new Meat("gongbaojiding")
gongbaojiding: Meat = [email protected]

scala> val shoushibaocai = new Meat("shoushibaocai")
shoushibaocai: Meat = [email protected]

scala> val meatPackage = packageFood(gongbaojiding,shoushibaocai)
meatPackage: Array[Meat] = Array([email protected], [email protected])

协变和逆变

  1. scala的协变和逆变完全解决了java中的泛型的一大缺憾
  2. 举例来说,java中,如果有professional是Master的子类,那么Card(Professionnal)是不是Card(Master)的子类呢?答案是:不是。
  3. 而scala中,只要灵活使用协变和逆变,就可以解决java泛型的问题
  4. 案例:进入会场
scala> :paste
// Entering paste mode (ctrl-D to finish)

class Master
class Professional extends Master

//大师以及大师级别以下的名片都可以进入会场
class Card[+T](val name:String)
def enterMeet(card:Card[Master])
 println("Welcome to have this meeting")



// Exiting paste mode, now interpreting.

defined class Master
defined class Professional
defined class Card
enterMeet: (card: Card[Master])Unit

scala> val leo = new Card[Master]("leo")
leo: Card[Master] = [email protected]

scala> val jack = new Card[Professional]("jack")
jack: Card[Professional] = [email protected]

scala> enterMeet(leo)
Welcome to have this meeting

scala> enterMeet(jack)
Welcome to have this meeting

scala> :paste
// Entering paste mode (ctrl-D to finish)

class Card[-T](val name:String)
def enterMeet(card:Card[Professional])
 println("welcome to have this meeting!")


// Exiting paste mode, now interpreting.

defined class Card
enterMeet: (card: Card[Professional])Unit

scala> val leo = new Card[Master]("leo")
leo: Card[Master] = [email protected]

scala> val jack = new Card[Professional]("jack")
jack: Card[Professional] = [email protected]

scala> enterMeet(leo)
welcome to have this meeting!

scala> enterMeet(jack)
welcome to have this meeting!

Existential Type

  1. 在scala中,有一种特殊的类型参数,就是Existential Type存在性类型。
Array[T] forSome type T
//占位符
Array[_]

spark基础-scala学习(代码片段)

函数式编程将函数赋值给变量匿名函数高阶函数高级函数的类型推断scala的常用高阶函数闭包sam转换currying函数return将函数赋值给变量scala中的函数是一等公民,可以独立定义,独立存在,而且可以直接将函数作为值赋值给变量sca... 查看详情

spark基础学习笔记09:scala基础(代码片段)

...模式。下面我们将在Scala的命令行操作模式中学习Scala的基础知识。一、变量声明(一)简单说明Scala中变量的声明使用关键字val和var。val类似Java中的final变量,也就是常量,一旦初始化将 查看详情

spark基础-scala学习(集合)(代码片段)

集合scala的集合体系结构ListLinkedListSet集合的函数式编程函数式编程综合案例:统计多个文本内的单词总数scala的集合体系结构scala中的集合体系主要包括:Iterable、Seq、Set、Map。其中Iterable是所有集合trait的根trait。这个结构与java... 查看详情

scala学习之一scala基础语法(代码片段)

环境  虚拟机:VMware10  Linux版本:CentOS-6.5-x86_64  客户端:Xshell4  FTP:Xftp4  jdk1.8  scala-2.10.4(依赖jdk1.8) spark-1.6Scala是一种混合功能编程语言,类似java,运行于JVM,集成面向对象编程和函数式编程的各种特性。(1)Scala... 查看详情

spark基础-scala学习(代码片段)

面向对象编程之Traittrait基础知识将trait作为接口使用在trait中定义具体方法在trait中定义具体字段在trait中定义抽象字段trait高级知识为实例对象混入traittrait调用链在trait中覆盖抽象方法混合使用trait的具体方法和抽象方法trait的构... 查看详情

scala简介及基础语法(代码片段)

...变量SCALA_HOME=E: empscala-2.11.8PATH中加入%SCALA_HOME%in;四、Scala基础语法1)Scala程序的开始HelloWorldobjectHelloWorlddefmain(args:Array[String]):Unit=println("Hello,world!")2)Scala的数据类型Scala与java一样,有8种数值类型:Byte/Char/Short/Int/Long/Float/Double/Bo... 查看详情

spark基础学习笔记13:scala函数(代码片段)

文章目录零、本讲学习目标一、声明函数(一)显式声明函数1、声明格式2、注意事项3、案例演示(二)隐式声明函数1、声明格式2、注意事项3、案例演示二、Scala函数种类(一)成员方法1、基本概念2、... 查看详情

spark基础学习笔记08:scala简介与安装(代码片段)

文章目录零、本讲学习目标一、Scala简介(一)Scala概述(二)函数式编程(三)Scala特性1、一切都是对象2、一切都是函数3、一切都是表达式(四)在线运行Scala二、Windows上安装Scala(一)... 查看详情

spark基础学习笔记10:scala集成开发环境(代码片段)

...境会在两种集成开发环境里创建Scala项目在上一讲《Spark基础学习笔记09:Scala基础》里,我们都是利用ScalaShell交互式环境来学习Scala基础知识,虽然交互式有快捷的优点,但是要写比较完整的程序,编辑就显得... 查看详情

scala零基础教学61-80

第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析 第62讲:Scala中上下文界定内幕中的隐式参数与隐式参数的实战详解及其在Spark中的应用源码解析/***Scala中上下文界定内幕中的隐式参数与隐... 查看详情

spark学习scala语法(代码片段)

一,变量1,基本数据类型2,基本运算符3,定义变量4,复杂变量 (1)定义数组Array:  声明:valaList=newArray[数据类型type](n):声明存储数据类型为type的n个对象,数组初始化为null  声明:valaList=Array(n1,n2,n3...... 查看详情

scala中的implicit

掌握implicit的用法是阅读Spark源码的基础,也是学习Scala其它的开源框架的关键,implicit可分为:隐式参数隐式转换类型隐式调用函数1.隐式参数当我们在定义方法时,可以把最后一个参数列表标记为implicit,表示该组参数是隐式参... 查看详情

spark常用编程技巧(代码片段)

Spark常用编程技巧文章目录Spark常用编程技巧1.基础篇1.1Scala篇1.2Spark篇2.进阶篇2.1Spark篇Spark常用编程技巧1.基础篇1.1Scala篇1.2Spark篇2.进阶篇2.1Spark篇SparkVersion:2.2.01.基础篇1.1Scala篇求均值描述:求一个Double类型的均值,含有Na... 查看详情

spark常用编程技巧(代码片段)

Spark常用编程技巧文章目录Spark常用编程技巧1.基础篇1.1Scala篇1.2Spark篇2.进阶篇2.1Spark篇Spark常用编程技巧1.基础篇1.1Scala篇1.2Spark篇2.进阶篇2.1Spark篇SparkVersion:2.2.01.基础篇1.1Scala篇求均值描述:求一个Double类型的均值,含有Na... 查看详情

大数据spark学习:scala基础第一课

计划:阶段1:精通Spark内核阶段2:精通千万级的项目阶段3:机器学习JAVA本身不是伟大的语言,伟大的是JVM,构件分布式平台什么的,依赖的是JVM,不一定要JAVA语言可认为Scala是JAVA的升级语言,JAVA是支持面向对象的语言,而非... 查看详情

spark学习二

...输入源常见RDD的方法叫textFile()方法今天安装Scala,并学习了Scala语言一些基本的语法,scala方法声明格式:deffunctionName([参数列表]):[returntype]例:objectadd  defaddInt(a:Int,b:Int):Int=     varsum:Int=0   ... 查看详情

大数据学习06scala的基础语法(代码片段)

大数据学习06Scala的基础语法介绍Scala的基础语法文章目录大数据学习06Scala的基础语法前言一、注释二、变量与常量1.基本语法2.代码实操三、标识符的命名规范1.命名规范2.字符串输出3.调试效果四、控制台标准输入1.代码实现2.调... 查看详情

spark机器学习速成宝典基础篇01windows下spark开发环境搭建+sbt+idea(scala版)

 注意:spark用2.1.1scala用2.11.11材料准备 spark安装包JDK8IDEA开发工具scala2.11.8  (注:spark2.1.0环境于scala2.11环境开发,所以必须版本对应 scala不是必须安装的,如果你是打算使用scala进行spark开发,则需要安装环境搭... 查看详情