首页 > 其他分享 >scala 快速上手

scala 快速上手

时间:2022-09-24 19:14:14浏览次数:74  
标签:String val scala Int fun println 快速 def

Scala 特性

  • 基于 JVM:可以与 Java 混合编程,且可相互调包。
  • 类型推测:不需要显式定义数据类型,\(var\) 表示变量,\(val\) 表示常量。
  • 并发和分布式(Actor,类似 Java 中的多线程 Thread)。
  • Trait 特性:类似于 Java 中的 interfaces 和 abstract 结合。
  • 模式匹配:match case (类似 Java 中的 switch case)。

类与对象

类 Class

  • 可以传参数,且要指定参数类型。有了参数后默认有了构造函数,且属性有了 \(getter、setter\) 方法。
  • 类中可以直接写执行代码,不需要定义函数。因为类在 \(new\) 的时候,除了方法(不包括构造函数)不执行,其余均执行。
  • 在同一个 scala 文件中,如果类名与对象名相同时,此时类叫做对象的伴生类,对象叫做类的伴生对象,他们之间可以互相访问私有变量。

对象 Object

  • 相当于类的单例对象,不需要使用 \(new\) 实例化。
  • 对象中的构造器会在第一次使用时会被执行。如果一个对象从未被调用,它的构造器也不会执行。
  • 对象不能传参数,除非是要 \(apply\) 方法。

函数

普通函数定义

  • 定义方法使用 def 关键字,格式def 方法名(参数列表:类型):返回值类型={方法体}
  • 方法体中最后返回值可以使用 return 。如果使用 return ,返回值类型一定要指定。相反,如果方法体中没有 return ,则默认返回方法体中最后一行计算的结果,此时返回值类型可以省略。
  • 方法体如果可以一行解决,包含方法体的 {} 可以省略。
  • 如果定义方法时,方法名和方法体之间的 = 被省略了,此方法最后会返回空值 unit
def max(a: Int, b: Int): Int ={
    if(a > b){
     return a
    } else {
     return b
    }
 }

def max(a: Int, b: Int) ={
    if(a > b){
     a
    } else {
      b
    }
}

def max(a: Int, b: Int) = if(a > b) b else a

递归函数

  • 递归方法要显式的指明返回类型
def fun(num: Int): Int ={
  if(num == 1) 1 else num * fun(num - 1)
}
println(fun(5))

默认值参数的函数

def fun(a: Int = 100, b: Int = 200) = a + b
println(fun(1, 2))  // 对应位置 3
println(fun(1))  // 最后一位 201
println(fun(a = 1, b = 2))  // 指定参数 3

变长参数的函数

def fun(s:String*) ={
  for(elem <- s) {
    println(elem)
  }
  // foreach
  s.foreach(elem => {println(elem)})
  // 简化
  s.foreach(println(_))
  // 再简化
  s.foreach(println)
}
fun("hello", "world", "scala")

匿名函数

  • 只要出现 => ,就是匿名函数
val stringToUnit: String => Unit = (s: String) => println(s)
stringToUnit("Hello")

嵌套函数

def outerFun(number: Int) ={
  def innerFun(num: Int): Int ={
    if(num == 1) 1
    else num * innerFun(num - 1)
  }
  innerFun(number)
}
println(outerFun(5))

偏应用函数

  • 某些情况下,方法参数非常多,且该方法多次调用,但是其中有些参数固定不变,则可以定义偏应用函数。
val data = new Date()
def showLog(date: Date, str: String) ={
  println(s"date is $date, log is $str")
}
def fun = showLog(data, _:String)
fun("a")
fun("b")

高级函数

参数是函数

def sum(a:Int, b:Int) = a + b
def fun(f:(Int, Int) => Int, str:String): String ={
  val sum = f(100, 200)
  str + sum
}
println(fun(sum, "sum = "))
// 或者
println(fun((a:Int, b:Int) => a * b, "mul = "))

返回是函数

  • 必须显式的写出返回函数的类型
  • 如果不显式写出,需要在返回函数后面加上 _
def fun(str:String): (String, String) => String ={
  def retFun(str1:String, str2:String): String = str + str1 + str2
  retFun
}
println(fun("1")("2", "3"))

// 不显式的话
def fun(str:String) ={
  def retFun(str1:String, str2:String): String = str + str1 + str2
  retFun _
}

两者都是函数

def fun(f:(Int, Int) => Int): (String, String) => String ={
  val sum = f(1, 2)
  def retFun(str1:String, str2:String): String ={
    str1 + str2 + sum
  }
  retFun
}
println(fun((a, b) => a + b)("a + ", "b = "))

柯里化函数

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

字符串和集合

map() 与 flatmap()

val list = List[String]("hello scala", "hello java", "hello spark")
val result1 = list.map(s => {
  s.split(" ")
})
val result2 = list.flatMap(s => {
  s.split(" ")
})
result1.foreach(arr => {arr.foreach(println)})
result2.foreach(println)

map与flatmap

数组 Array

// 不可变长数组
val arr = Array[String]("a", "b", "c")

// 定义长度为3的数组arr1
val arr1 = new Array[Int](3)
arr1(0) = 2;

// 打印
arr.foreach(elem=>println(elem))
arr.foreach(println(_))
arr1.foreach(println)

// 可变长数组
var arr2 = ArrayBuffer[Int](1, 2, 3)

// append 等同于  += ,新增元素在数组最后面
arr2.append(6)
arr2.+=(7)

//  +=: 则是新增元素在数组最前面
arr2.+=:(8)

// 二维数组
val secArray = new Array[Array[String]](10)
for(index <- 0 until secArray.length){
  secArray(index) = new Array[String](10)
}

列表 List

// 定长列表 list
val list = List[String]("hello world", "hello scala")

// filter方法,过滤器,匹配上了就保留,否则舍弃
val value: List[String] = list.filter(s => {
    "hello world".equals(s)
})

// 可变长列表 list
var list2 = ListBuffer[Int](1, 2, 3)

//  append 等同于  += ,新增元素在数组最后面
list2.append(6)
list2.+=(7)
//  +=: 则是新增元素在数组最前面
list2.+=:(8)

集合 Set

// 无序,去重
val set = Set[Int](1, 2, 3, 4)
val set1 = Set[Int](3, 4, 5, 6)

// 并集
set.concat(set1).foreach(println)
// 交集
set.intersect(set1).foreach(println)
// 差集
set.diff(set1).foreach(println)

// 可变 set
import scala.collection.mutable
val set2 = mutable.Set[Int](1, 2, 3)
set2.add(5)

// 不可变 set
import scala.collection.immutable
val set3 = immutable.Set[Int](1,2,3)

// 转成数组,list
set1.toArray.foreach{println}
set1.toList.foreach{println}

集合 Map

val map = Map[String, Int]("a" -> 100, "b" -> 200, "c" -> 300, "e" -> 500)
val map2 = Map[String,Int](("a", 1),("b", 2),("c", 3),("d", 4))
map.foreach(println)

// 获取 key 为 ‘a’ 的 value
val value1: Option[Int] = map.get("a")

// 获取 map 中所有 key
val keys: Iterable[String] = map.keys

// 获取 map 中所有 value
val values: Iterable[Int] = map.values

// map2 追加到 map 中,相同 key 的 value 会被替换
map.++(map2).foreach(println)
// map 追加到 map2中
map.++:(map2).foreach(println)

// 可变长 Map
val map3 = mutable.Map[String,Int](("a", 1),("b", 2))
map3.put("c", 3)

// 过滤掉 map 中 value 小于 2
map3.filter(tem=>{
    val key = tem._1
    var value = tem._2
    value >= 2
}).foreach(println)

元组 Tuple

  • () 中放入一堆元素就叫元组,元素类型可不同。
  • 最多支持 22 个元素。
  • 元组可不 new
  • 只有二元元组能使用swap
val tuple2 = (1, 2)

// 打印元组第 2 个元素
println(tuple2._2)

// 遍历元组
val iterator: Iterator[Any] = tuple2.productIterator
iterator.foreach(println)

// 二元元组的翻转
println(tuple2.swap)

// toString 方法
println(tuple2.toString())

Trait 特性

  • Trait 相当于 Java 的接口。
  • Trait 可以定义属性和方法的实现,相当于 Java 中抽象类和接口的结合。
  • 类可以继承多个 Trait,第一个用 extends ,后面用 with
  • 继承的多个 Trait 中如果有同名的方法和属性,必须要在类中使用 override 重新定义。
  • Trait 中不可传参数。
trait IsEqual {
  def isEqual(obj: Any): Boolean
  def notIsEqual(obj: Any): Boolean = !isEqual(obj)
}

class Point(x: Int, y: Int) extends IsEqual{
  val xPoint = x
  val yPoint = y

  override def isEqual(obj: Any): Boolean = {
    obj.isInstanceOf[Point] && obj.asInstanceOf[Point].xPoint == this.xPoint
  }
}

object TraitLearning {
  def main(args: Array[String]): Unit = {
    val point1 = new Point(1, 2)
    val point2 = new Point(1, 3)
    println(point1.isEqual(point2))
    println(point1.notIsEqual(point2))
  }
}

模式匹配 Match

  • 类似与 Java 中的 switch case
  • 不仅可以匹配值,还可以匹配类型(类型的匹配也必须要有变量名)。
  • 模式匹配中,从上到下顺序匹配。
  • 如果都不匹配,会匹配到 case _ ,相当于 default
  • 模式范围小的应该在最前面。
def main(args: Array[String]): Unit = {
  val tuple = (1, 1.2, "scala", true)
  val iterator = tuple.productIterator
  iterator.foreach(item => MatchTest(item))
}

def MatchTest(obj: Any) = {
  obj match {
    case 1 => println("value is 1")
    case i:Int => println(s"type is int, value = $i")
    case d:Double => println(s"type is double, value = $d")
    case _ => println("no matching")
	}
}

偏函数

  • 在模式匹配中,只有 case 而没有 match ,就可以将其定义为偏函数。
  • 只能匹配相同类型,更接近于 Java 中的 switch case
object PartialFunction {
  def Test: PartialFunction[String, Int] = {
    case "a" => 1
    case _ => 2
  }

  def main(args: Array[String]): Unit = {
    val res = Test("a")
    println(res)
  }
}

样例类

  • 使用关键字 case 修饰的类,就叫做样例类。
  • 样例类默认实现了类构造函数的 getter 方法(构造函数的参数默认是 val),如果参数是 var 类型,则实现了 gettersetter 方法。
  • 样例类可以 new 也可以不 new
case class Person(name: String, age: Int)

object CaseClass {
  def main(args: Array[String]): Unit = {
    val person = new Person("scala", 22)
    println(person)
  }
}

隐式转换

定义

在 \(Scala\) 编译器进行类型匹配时,如果找不到合适的类型,那么隐式转换会让编译器在作用范围内自动推导出来合适的类型。

隐式值与隐式参数

  • 同类型的参数的隐式值在作用域中只能出现一次
  • 如果方法中有部分参数需要隐式转换,则需要使用柯里化,且隐式参数放在第二个括号中。
def sayName(implicit name: String): Unit ={
  println(s"the name is $name")
}

// 部分参数需要隐式转换
def sayNameAndAge(age: Int)(implicit name: String)={
  println(s"the name is $name,the age is $age")
}

def main(args: Array[String]): Unit = {
  implicit val name = "scala"
  sayName
  sayName("spark")
  sayNameAndAge(22)
  sayNameAndAge(22)("spark")
}

隐式转换函数

如果类 A 调用了 fun 函数,但是类 A 中没有实现 fun 函数,而类 B 中却实现了此函数。那么编译器就会去找隐式转换函数(将类 A 转换为类 B)

  • 隐式转换函数只与函数的参数类型和返回类型有关,与函数名称无关。(即不能存在两个类型相同的隐式转换函数)。
class Animal(name: String){
  def canFly()={
    println(s"$name can fly")
  }
}

case class Bird(name: String)

object ImplicitFun {
  implicit def birdToAnimal(bird: Bird) = new Animal(bird.name)

  def main(args: Array[String]): Unit = {
    val bird = new Bird("scala")
    bird.canFly()
  }
}

隐式类

如果类 A 没有某种方法或者属性,而类 A 要去调用某种方法,此时可以通过隐式类来实现。

  • 使用 implicit 定义的类,只能定义在类、包对象、伴生对象中
  • 隐式类的构造必须只有一个参数,否则无法识别。
  • 同一作用域中不能出现同类型构造的隐式类。
class Bird(xname:String){
  val name = xname
}

object ImplicitClass {
  implicit class Animal(B:Bird){
    def canFly()={
      println(s"${B.name} can fly")
    }
  }

  def main(args: Array[String]): Unit = {
    val bird = new Bird("scala")
    bird.canFly()
  }
}

参考资料:

视频:https://www.bilibili.com/video/BV1oJ411m7z3

博客:https://blog.csdn.net/weixin_42142364/article/details/113430109

博客:https://blog.csdn.net/qq_44104303/article/details/117951267

标签:String,val,scala,Int,fun,println,快速,def
From: https://www.cnblogs.com/fireonfire/p/16726279.html

相关文章

  • Servlet快速入门
     创建Servlet:创建web项目,导入Servlet依赖坐标<dependency><groupld>javax.servlet</groupld><artifactld>javax.servlet-api</artifactld><version>3.1.0</version>......
  • Maven快速配置和入门
    概念Maven其实就是一个管理项目、构建项目的工具。它有标准化的项目结构、构建流程、依赖管理。功能Maven提供了一套标准的项目结构Maven提供了一套标准的构建流程Ma......
  • LOJ #162. 快速幂 2
    题意要求一个\(O(\sqrtP)-O(1)\)的快速幂。幂可以用扩展欧拉定理规约到\([1,P-1]\)中。分析分块。定个阈值\(B=\sqrtP\)+1。\(a^t=a^{t\bmodB}\cdot......
  • 快速排序
    简介快速排序(Quicksort)是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再......
  • 前后端开发模式、API接口、接口测试工具postman、restful规范、序列化和反序列化、dja
    目录前后端开发模式一、两种模式1.传统开发模式:前后端混合开发1.1.缺点:2.前后端分离开发模式2.1.特点3.补充老刘的相关博客:二、API接口1.作用2.说明三、接口测试工具postm......
  • API接口、接口测试工具postman、restful规范、序列化与反序列化、djangorestframework
    API接口通过网络,规定了前台后台信息交流规则的url链接,也就是前后台信息交互的媒介API接口的样子url:长得像返回数据的url链接https://api.map.baidu.com/place/v2/s......
  • 易优cms忘记后台登陆密码?解决方法 Eyoucms快速入门
    忘记后台管理密码怎么搞? 方法一:下载官方易优修改重置后台密码小工具 https://www.eyoucms.com/uploads/soft/200319/1-2003191Q000.zip下载附件后解压,将setpwd.php......
  • 零基础使用 WebGL — 快速入门
    WebGL作为一个非常底层的API,学习和使用起来非常困难,因为WebGL需要大量的背景知识。网上教程一般都是介绍API就开始渲染,介绍不多,容易让人迷惑,也容易被劝退。即使你学会......
  • 快速稳定盈利的四个步骤
    控制自己不会有大幅度的回撤是稳定盈利的第一步。如何去控制回撤呢?第一是你要记录你对所有模式的实操情况。然后记录下来。比如你用半路战法的时候最大的一次日回撤是多少......
  • 快速上手React编程 pdf
    高清扫描版下载链接:https://pan.baidu.com/s/1R4B-izNpESydo-yFNmU8xw点击这里获取提取码 ......