========================scala函数========================================
Scala函数可以直接赋值给变量,语法规定,将函数赋值给变量时,必须在函数名后面加上空格和下划线
def sayHello(name: String) = { println("Hello, " + name) }
val sayHelloFunc = sayHello _
sayHelloFunc("leo")
** 匿名函数的语法: (参数名: 参数类型) => 函数体
def sayHelloFunc = (name: String) => println("Hello, " + name)
sayHelloFunc("leo")
-------------------—/高阶函数/---------------------------------------
def greeting(func: (String) => Unit, name: String) { func(name) }
greeting(sayHelloFunc, "leo")
//函数作为返回值
def getGreetingFunc(msg: String) = (name: String) => println(msg + ", " + name)
//val greetingFunc = getGreetingFunc("hello")
//greetingFunc("张三")
getGreetingFunc("hello")("张三")
-------------------------------自动类型推断---------------------
def greeting(func: (String) => Unit, name: String) { func(name) }
greeting((name: String) => println("Hello, " + name), "leo")
//高阶函数可以自动推断出参数类型
greeting((name) => println("Hello, " + name), "leo")
//对于只有一个参数的函数,可以省去其小括号
greeting(name => println("Hello, " + name), "leo")
//见下
greeting(println(_), "leo")
//greeting(println("Hello, " + _), "leo") //错误,此种语法不是万能的
-------------
def double(x :Int,func: (Int) => Int) = { func(x) }
//如果仅有的一个参数在右侧的函数体内只使用一次,则还可以将接收参数省略,并且将参数用_来替代
------------------------/常用高阶函数/------------------
//依次处理每个元素,并返回处理后的元素的集合
for(x <- Array(1, 2, 3, 4, 5).map(2 * _))
print(x+" ")
println("a"*3)
//对传入的每个元素进行处理,但是没有返回值
(1 to 9).map("*" * _).foreach(println _) //println后面的_也可以省略
//对每个元素都进行判定,结果为true则保留,否则删除
for(x <- (1 to 10).filter(_ % 2 == 0))
print(x+" ")
//从左侧开始,进行reduce操作,即先对元素1和元素2进行处理,然后将结果与元素3进行处理,依次类推...
println((1 to 10).reduceLeft( _ + _ ))//左边开始计算,第一计算的的结果输出到下个计算数据的左边
println((1 to 10).reduceRight( _ - _ ))//右边开始计算,倒数第二个减去倒数第一个,得出的结果放到下个计算数据的右边。
===================隐式转换============================================
** 只要在程序可见范围内定义了隐式转换函数,就会被Scala自动调用
** 隐式转换函数的名字可以任意,建议命名为“xxx2yyy”的形式
** 以implicit开头,而且最好定义函数返回类型
def main(args:Array[String]): Unit ={
class Student(val name: String)
class Older(val name: String)
class SpecialPerson(val name: String)
implicit def object2SpecialPerson (obj: Object): SpecialPerson = {
if (obj.getClass == classOf[Student]) {
val stu = obj.asInstanceOf[Student];
new SpecialPerson(stu.name)
}
else if (obj.getClass == classOf[Older]) {
val older = obj.asInstanceOf[Older]
new SpecialPerson(older.name)
}
else null
}
var ticketNumber = 0
def buySpecialTicket(p: SpecialPerson) = {
ticketNumber += 1
"T-" + ticketNumber
}
val a=new Student("aaa")
println(buySpecialTicket(a))
val b=new Older("bbb")
println(buySpecialTicket(b))
}
--------------------------隐式转换-----------------
** 隐式转换的强大之处就是可以增强现有类的功能
** 如果隐式转换函数不在可见范围内,那就必须使用import来导入,如:import xxx._
class Man(val name: String)
class Superman(val name: String) {
def emitLaser = println("emit a laster!")
}
implicit def man2superman(man: Man): Superman = new Superman(man.name)
val leo = new Man("leo")
leo.emitLaser
** Scala什么时候会进行隐式转换?
1 调用某个函数,但传入参数的类型与函数定义的参数类型不匹配(函数)
2 调用某个方法,虽然该类有这个方法,但给方法传入的参数类型,与方法定义的参数类型不匹配(方法)
3 使用某个对象,调用某个方法,但这个方法并不存在于该类时
------------------------隐式参数---------------------
** 在函数或方法中,用implicit来修饰的参数即为隐式参数
** Scala会尝试找到一个对应类型的、用implicit修饰的对象,即隐式值,并将其作为参数自动注入
** Scala会在两个范围内查找:一个是当前作用域内可见的val或var定义的隐式变量
** 另一个是隐式参数类型的伴生对象内的隐式值
class SignPen {
def write(content: String) = println(content)
}
implicit val pen = new SignPen
def signForExam(name: String) (implicit signPen: SignPen) {
signPen.write(name + " come to exam in time.")
}
signForExam("aaa")
==========================特质triat================================
** triat与Java中的接口非常类似,在triat中可以定义抽象方法
** 使用extends关键字继承trait
** Scala不支持类的多继承,但支持trait多继承,使用with关键字即可
** 类继承trait后,必须实现其中的抽象方法
trait HelloTrait {
def sayHello(name: String)
}
trait MakeFriendsTrait {
def makeFriends(p: Person)
}
class Person(val name: String) extends HelloTrait with MakeFriendsTrait {
def sayHello(name: String) = println("Hello, " + name)
def makeFriends(p: Person) = println("my name: " + name + ", your name: " + p.name)
}
def main(args:Array[String]): Unit ={
val a=new Person("aaa")
a.sayHello("bbb")
val b=new Person("bbb")
a.makeFriends(b)
}
----------------------------------
** triat中可以定义具体字段,也可以定义抽象字段
** triat中可以定义抽象方法,也可以定义具体方法
** trait中的具体方法可以基于抽象字段来编写
trait T{
val x=10
val y:Int //抽象字段,没有赋初值
def f() = println("T:"+y)
}
class A extends T{
val y=100 //实现抽象字段
}
def main(args:Array[String]): Unit ={
val a=new A()
println(a.x+" "+a.y)
a.f()
}
----------------------------------
** scala支持对象混入多个特质,当调用同名方法时,最右边特质内的方法会被首先调用
** super指的是其左边的特质,只有当左边没有特质时,才会指向其父特质
Scala函数可以直接赋值给变量,语法规定,将函数赋值给变量时,必须在函数名后面加上空格和下划线
def sayHello(name: String) = { println("Hello, " + name) }
val sayHelloFunc = sayHello _
sayHelloFunc("leo")
** 匿名函数的语法: (参数名: 参数类型) => 函数体
def sayHelloFunc = (name: String) => println("Hello, " + name)
sayHelloFunc("leo")
-------------------—/高阶函数/---------------------------------------
//函数作为参数
val sayHelloFunc = (name: String) => println("Hello, " + name)def greeting(func: (String) => Unit, name: String) { func(name) }
greeting(sayHelloFunc, "leo")
//函数作为返回值
def getGreetingFunc(msg: String) = (name: String) => println(msg + ", " + name)
//val greetingFunc = getGreetingFunc("hello")
//greetingFunc("张三")
getGreetingFunc("hello")("张三")
-------------------------------自动类型推断---------------------
def greeting(func: (String) => Unit, name: String) { func(name) }
greeting((name: String) => println("Hello, " + name), "leo")
//高阶函数可以自动推断出参数类型
greeting((name) => println("Hello, " + name), "leo")
//对于只有一个参数的函数,可以省去其小括号
greeting(name => println("Hello, " + name), "leo")
//见下
greeting(println(_), "leo")
//greeting(println("Hello, " + _), "leo") //错误,此种语法不是万能的
-------------
def double(x :Int,func: (Int) => Int) = { func(x) }
//如果仅有的一个参数在右侧的函数体内只使用一次,则还可以将接收参数省略,并且将参数用_来替代
println(double(5, 2 * _ )) //正确,x=>2*x
‘
------------------------/常用高阶函数/------------------
//依次处理每个元素,并返回处理后的元素的集合
for(x <- Array(1, 2, 3, 4, 5).map(2 * _))
print(x+" ")
println("a"*3)
//对传入的每个元素进行处理,但是没有返回值
(1 to 9).map("*" * _).foreach(println _) //println后面的_也可以省略
//对每个元素都进行判定,结果为true则保留,否则删除
for(x <- (1 to 10).filter(_ % 2 == 0))
print(x+" ")
//从左侧开始,进行reduce操作,即先对元素1和元素2进行处理,然后将结果与元素3进行处理,依次类推...
println((1 to 10).reduceLeft( _ + _ ))//左边开始计算,第一计算的的结果输出到下个计算数据的左边
println((1 to 10).reduceRight( _ - _ ))//右边开始计算,倒数第二个减去倒数第一个,得出的结果放到下个计算数据的右边。
===================隐式转换============================================
** 只要在程序可见范围内定义了隐式转换函数,就会被Scala自动调用
** 隐式转换函数的名字可以任意,建议命名为“xxx2yyy”的形式
** 以implicit开头,而且最好定义函数返回类型
def main(args:Array[String]): Unit ={
class Student(val name: String)
class Older(val name: String)
class SpecialPerson(val name: String)
implicit def object2SpecialPerson (obj: Object): SpecialPerson = {
if (obj.getClass == classOf[Student]) {
val stu = obj.asInstanceOf[Student];
new SpecialPerson(stu.name)
}
else if (obj.getClass == classOf[Older]) {
val older = obj.asInstanceOf[Older]
new SpecialPerson(older.name)
}
else null
}
var ticketNumber = 0
def buySpecialTicket(p: SpecialPerson) = {
ticketNumber += 1
"T-" + ticketNumber
}
val a=new Student("aaa")
println(buySpecialTicket(a))
val b=new Older("bbb")
println(buySpecialTicket(b))
}
--------------------------隐式转换-----------------
** 隐式转换的强大之处就是可以增强现有类的功能
** 如果隐式转换函数不在可见范围内,那就必须使用import来导入,如:import xxx._
class Man(val name: String)
class Superman(val name: String) {
def emitLaser = println("emit a laster!")
}
implicit def man2superman(man: Man): Superman = new Superman(man.name)
val leo = new Man("leo")
leo.emitLaser
** Scala什么时候会进行隐式转换?
1 调用某个函数,但传入参数的类型与函数定义的参数类型不匹配(函数)
2 调用某个方法,虽然该类有这个方法,但给方法传入的参数类型,与方法定义的参数类型不匹配(方法)
3 使用某个对象,调用某个方法,但这个方法并不存在于该类时
------------------------隐式参数---------------------
** 在函数或方法中,用implicit来修饰的参数即为隐式参数
** Scala会尝试找到一个对应类型的、用implicit修饰的对象,即隐式值,并将其作为参数自动注入
** Scala会在两个范围内查找:一个是当前作用域内可见的val或var定义的隐式变量
** 另一个是隐式参数类型的伴生对象内的隐式值
class SignPen {
def write(content: String) = println(content)
}
implicit val pen = new SignPen
def signForExam(name: String) (implicit signPen: SignPen) {
signPen.write(name + " come to exam in time.")
}
signForExam("aaa")
==========================特质triat================================
** triat与Java中的接口非常类似,在triat中可以定义抽象方法
** 使用extends关键字继承trait
** Scala不支持类的多继承,但支持trait多继承,使用with关键字即可
** 类继承trait后,必须实现其中的抽象方法
trait HelloTrait {
def sayHello(name: String)
}
trait MakeFriendsTrait {
def makeFriends(p: Person)
}
class Person(val name: String) extends HelloTrait with MakeFriendsTrait {
def sayHello(name: String) = println("Hello, " + name)
def makeFriends(p: Person) = println("my name: " + name + ", your name: " + p.name)
}
def main(args:Array[String]): Unit ={
val a=new Person("aaa")
a.sayHello("bbb")
val b=new Person("bbb")
a.makeFriends(b)
}
----------------------------------
** triat中可以定义具体字段,也可以定义抽象字段
** triat中可以定义抽象方法,也可以定义具体方法
** trait中的具体方法可以基于抽象字段来编写
trait T{
val x=10
val y:Int //抽象字段,没有赋初值
def f() = println("T:"+y)
}
class A extends T{
val y=100 //实现抽象字段
}
def main(args:Array[String]): Unit ={
val a=new A()
println(a.x+" "+a.y)
a.f()
}
----------------------------------
** scala支持对象混入多个特质,当调用同名方法时,最右边特质内的方法会被首先调用
** super指的是其左边的特质,只有当左边没有特质时,才会指向其父特质