Scala入门

Scala

多范式编程语言(面向对象编程和函数式编程),开发环境需要安装scala,部署环境有java环境即可正常运行

重点:高阶函数,即函数可以作为参数传递

六大特性

  • 混编
  • 类型自动推断
  • 适合高并发和分布式
  • 特征特质trait
  • 模式匹配
  • 高阶函数

数据类型

  • any
    • anyref
      • nothing
    • anyval
      • nothing
  • 基本数据类型同java
  • unit表示空值
  • nil表示长度为0的list

开发特点

  1. 没有类似于static的关键字,不能通过关键字修饰静态属性、方法、代码块,Object中所有内容均为静态

  2. 重写构造器时,要先调用默认构造器

    def this(myname: String, myage: Int, mymoney: Int) {
      this(myname, myage);
      money = mymoney
    }
    
  3. class和Object名字相同时互为伴生类和伴生对象,可以互相访问私有属性

  4. 没有自增符号 ++ --,可以使用 +=

  5. to/until的使用

    println(1 to 10)
    println(1 to (10, 2))
    println(1 until(10))
    
  6. for循环

    for (i <- 1 to 10) {
      println(i)
    }
    for (i <- 1 to 10; if i > 5) {
      println(i)
    }
    for (i <- 1 to 9; j <- 1 to i) {
      print(i + "*" + j + "=" + i * j + " ")
      if (i == j)
        println()
    }
    
  7. 自动将函数的最后一行作为返回值,可以省略return

  8. 隐式推断:scala具有类型自动推断的特性,可以省略返回类型,如果使用return,则必须声明返回类型

函数

递归函数

def factorial(n: Int): Int = {  
  if (n <= 1)
     1  
  else    
     n * factorial(n - 1)
}

有默认值参数的函数

def main(args: Array[String]) {
   println( "Returned Value : " + addInt() );
}
 
def addInt( a:Int = 5, b:Int = 7 ) : Int = {
   var sum:Int = 0
   sum = a + b
 
   return sum
}

可变参数函数

def main(args: Array[String]) {
   printStrings("Hello", "Scala", "Python");
}
 
def printStrings( args:String* ) = {
   var i : Int = 0;
 
   for( arg <- args ){
      println("Arg value[" + i + "] = " + arg );
      i = i + 1;
   }
}

偏应用函数

/**
 * 偏函数
 * 一个函数中只有case,没有match
 * 偏函数不一定会对所有元素进行操作,只会对偏函数感兴趣的元素去操作
 * 偏函数写法:没有参数,最重要的在于isDefinedAt和apply
 *
 * 举例:map和collect的区别
 */
def myTest:PartialFunction[String, String] = {
      //[String,String]第一个为入参类型,第二个为返回值类型
  case "scala" => {"scala"}
  case "hello" => {"hello"}
  case _ => {"no match"}
}

柯里化函数

def fun5(a:Int, b:Int)(c:Int, d:Int) = {
  a + b + c + d
}
println(fun5(1, 2)(3, 4))

匿名函数

//箭头左边是参数列表
//箭头右边是函数体
() => {}
var anon = (a:Int, b:Int) => {a+b}

高阶函数

//函数的参数是函数
//主函数(fun1)的其中一个参数,是一个规定了参数个数、参数类型、返回值类型的次函数(f)
//次函数(f)具体方法名可以在调用主函数(fun1)的时候通过传参(sum)进行确定
//次函数也可以为匿名函数,在主函数传参的时候进行定义
def fun1(a:Int, f:(Int, Int) => Int) = {
  var result = f(4, 4)
  println("------------")
  a * result
}
def sum(a:Int, b:Int) = {
  a + b
}
print(fun1(5, sum))
//传参为匿名函数
print(fun1(5, (a:Int, b:Int) => {a - b}))


//函数的返回值是函数
//返回值是一个规定了参数数量、参数类型、返回值类型的函数
def fun2(a:String, b:String) : (String, String) => String = {
  def fun3(c:String, d:String) = {
    a + b + c + d
  }
  fun3
}
val result: (String, String) => String = fun2("1", "2")
println(result("3", "4"))
println(fun2("1", "2")("3", "4"))


//参数和返回值均为函数
def fun4(f:(Int, Int) => Int) : (Int, Int) => Int = {
  f
}
println(fun4((a:Int, b:Int) => {a + b})(1, 2))
println(fun4(_+_)(3, 4))

开发方法

数组

/**
  * 数组创建、遍历、方法举例
  */
val array: Array[Int] = Array(1, 2, 3)

for (i <- array) {
  println(i)
}

//foreach操作的是array中的每一个元素,参数传入匿名函数
array.foreach(i => println(i))

//多维数组
val arr4 = Array[Array[Int]](Array(1,2), Array(3,4))
arr4.foreach(i => {
  i.foreach(j => {
    println(j)
  })
})

for (arr <- arr4; i <- arr) {
  println(i)
}

val arr1 = Array(1,2)
val arr2 = Array(3,4)
val array = Array.concat(arr1, arr2)
array.foreach(println)
val strings: Array[String] = Array.fill(5)("nihao")


/**
 * 可变长度数组
 */
val array = ArrayBuffer[String]("a", "b", "c")
array.append("e", "f")
array.+= ("1")//追加在数组尾
array.+=: ("2")//带: 追加在数组头部
array.foreach(println)

List

/**
 * List创建及方法举例
 */
val list = List(1, 2, 3)
list.foreach(println)
for (i <- list) {
  println(i)
}

//过滤元素
val result: List[Int] = list.filter(i => {
  if (i > 2) {
    true
  } else {
    false
  }
})
result.foreach(println)

//计算符合条件的元素个数
println(list.count(i =>true))



/**
 * 可变长度List
 */
val listBuffer = ListBuffer(1, 2, 3)
listBuffer.append(4)
listBuffer.+=:(0)
listBuffer.+=(5)
listBuffer.foreach(println)

Map

/**
 * map & flatmap
 * map:映射,将一个东西变成另一个东西,一进一出
 * flatmap:map + flat 业务逻辑处理+数据压平,支持一对多
 */
val list1: List[String] = list.map(i => i + "10")
list1.foreach(println)

val list2 = List("hello beijing", "hello shanghai", "hello guangzhou")
val stringses: List[Array[String]] = list2.map(line => line.split(" "))
stringses.foreach(i => {
  i.foreach(println)
})

val strings: List[String] = list2.flatMap(i => {
  i.split(" ")
})

strings.foreach(println)


val map = Map(
  "name" -> "zs",
  "sex" -> "man"
)
map.foreach(x => {
  x._1 + ":" + x._2
})

//scala推荐使用option对象来作为有可能返回空的函数的值得返回类型,option中包含两个对象(Some, None)
val option: Option[String] = map.get("name")
val option1: Option[String] = map.get("name2")
println(option)
println(option1)
println(option1.getOrElse("none"))
//一步单位
println(map.getOrElse("name", "none"))



/**
 * 遍历手段
 */
val keys: Iterable[String] = map.keys
keys.foreach(println)
keys.foreach(i => {
  println(map.get(i).get)
})
val set: Set[String] = map.keySet
set.foreach(println)
set.foreach(i => {
  println(map.get(i).get)
})
val values: Iterable[String] = map.values
values.foreach(println)
val map1 = Map(
  "name" -> "ls",
  "sex" -> "women"
)
val map2: Map[String, String] = map.++(map1)//以第一个为主map
val map3: Map[String, String] = map.++:(map1)//以第二个为主map
map2.foreach(println)
map3.foreach(println)
val map4 = Map(
  "one" -> 15,
  "two" -> 20,
  "three" -> 25
)
val filterresult = map4.filter(x => {
  if (x._2 >= 20) {
    true
  } else {
    false
  }
})
filterresult.foreach(println)
val countResult: Int = map4.count(x => {
  if (x._2 > 20) {
    true
  } else {
    false
  }
})
println(countResult)
val bool = map4.contains("one")
println(bool)
if (map4.contains("two")) {
  println(map.get("two"))
}
val bool1 = map4.exists(x => {
  if (x._2 > 20) {
    //exists会在找到符合逻辑的数据之后就停止遍历
    true
  } else {
    false
  }
})
println(bool1)


/**
 * 可变Map
 * scala.collection.mutable.Map
 */
val map: mutable.Map[String, Any] = Map(("name", "pzl"), ("age", 24))
//如果想要添加原来map中没有的value类型,要手动修改类型为[String, Any]
map+=(("money",1),("height",170))
map+=("weight" -> 140)
map-=("age")
map.foreach(println)

Set

val set1 = Set(1, 2, 3)
val set2 = Set(4, 5, 6)

//求并集
val set = set1.union(set2)

//求差集
val set3 = set1.diff(set2)

//求交集
val set4 = set1.intersect(set2)
val set5 = set1 & set2//交集
val set6 = set1 &~ set2//差集
val max = set.max
val list: List[Int] = set.toList
val str: String = set.mkString("$")
println(str)


/**
 * 可变set
 */
val set7 = mutable.Set(1, 2, 3)
//因为无序,所以set的追加方法不是append,是add
set7.add(4);
set7.+=(5,6,7,8)

Tuple元组

val tuple: (Int, Int) = new Tuple2(1, 2)
val tuple1: (Int, Int, Int) = Tuple3(1, 2, 3)
//创建二元组的特殊方式
val tuple2: (String, String) = "name" -> "zs"
val tuple4: (String, Int) = ("age", 18)
val tuple3: (Int, String, Float, Long) = Tuple4(1, "2", 3.0f, 4L)


/**
 * 遍历
 * 获取迭代器
 * 因为tuple元组本质上不是集合,但是在遍历的时候可以当做一个集合使用(迭代器)
 */
val productIterator: Iterator[Any] = tuple3.productIterator
while (productIterator.hasNext) {
  println(productIterator.next())
}


/**
 * 二元组的特殊方法
 */
val swap = tuple.swap
val productIterator: Iterator[Any] = swap.productIterator
while (productIterator.hasNext) {
  println(productIterator.next())
}
println(swap.toString())

Trait(特征)

类似于Java中的接口,可以定义属性和实现方法,并且可以多继承

trait Play {
  val name = "zs"
  def play() = {
    println("I'm playing")
  }
}

trait Study {
  val name = "ls"
  def study() = {
    println("I'm learning")
  }
}

class People extends Play with Study {
  //当继承的类中有重复的属性值时,需要重写属性
  override val name: String = "pzl"
}

object Test_Trait {
  def main(args: Array[String]): Unit = {
    val people = new People
    people.play()
    people.study()
  }
}

Match

def main(args: Array[String]): Unit = {
  val tuple: (Int, String, Float, Char) = (1, "2", 3.0f, 'd')
  val iterator = tuple.productIterator
  while(iterator.hasNext) {
    test_Match(iterator.next())
  }
}

def test_Match(x:Any): Unit = {
  x match {
    case 1 => println(1)
    case "2" => println("2")
      //将大类型放在后面,先看看能不能获取到更加精准的结果
    case x:String => println("is String")
    case _ => println("no")
  }
}

Implicit

/**
 * 隐式转换是在scala编译器进行类型匹配时,如果找不到合适的类型
 * 那么隐式转换会让编译器在作用范围内自动推导出合适的类型
 */

/**
 * 隐式值与隐式参数
 * 当以隐式参数作为参数的方法被调用但没有传参的时候
 * 自动将作用域范围内的隐式值作为参数(类型一致)
 */
implicit val address = "shanghai"
implicit val age = 18

def test(implicit x:String) = {
  println(x)
}

def test2(implicit x:String = "beijing") = {
  println(x)
}

/**
 * 多参数情况下,要用柯里化函数,并且将隐式参数放在最后面
 * @param x
 * @param y
 */
def test3(x:String = "beijing")(implicit y:Int) = {
  println(x + y)
    
}
def main(args: Array[String]): Unit = {
  test("zs")
  test
  test2
  test2()
  test3()
  test3()(24)
}



/**
 * 隐式转换函数
 * 当A想要调用B中的方法时
 * scala会在作用域范围内寻找是否有能把A转换成B的隐式转换函数
 * 如果有则可以调用B中方法
 */
class Bird (name:String) {
   def fly() = {
     println("flying")
   }
}
class Pig (xname:String) {
  val name = xname
}
object Test2_implicit {
  implicit def toBird(a:Pig): Bird = {
    new Bird(a.name)
  }
  var pig = new Pig("zs")
  pig.fly()
}



/**
 * 隐式类
 * 必须定义在类、包对象、伴生对象中
 * 构造必须只有一个参数
 * 同一个类、包对象、伴生对象中不能出现同类型构造的隐式类
 */
class Rabbit(xname:String) {
  val name = xname
}
object Test3_implicit {
  /**
   * 作为参数传递进来的类型,可以调用这个隐式类中的属性和方法
   * @param rat
   */
  implicit class Animal(rat:Rabbit) {
    val age = 18
    def eat() = {
      println("eating")
    }
  }
  def main(args: Array[String]): Unit = {
    val rabbit = new Rabbit("zs")
    rabbit.eat()
    println(rabbit.age)
  }
}

Actor

scala中的actor在2.12版本中从scala标准库中移除,想要调用actor,需要引入akka-actor包来使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值