Scala入门笔记一之函数和数据结构

Scala简介:

Scala是Scalable Language 的简写,是一门多范式的,纯面向对象的语言,每个值都是对象。同时Scala也是一种函数式语言,其函数也能当成值来使用。由于Scala整合了面向对象语言和函数式编程的特性,因此Scala相对于Java、C#、C++等其他语言更加简洁。

不同于Java,Scala中没有原生的数据类型,数据分为两种类型,常量(以字母或下划线开头)和变量(不能有$符号)。Scala 中的数据类型都是对象,可以对数据类型调用方法。另外,所有数据类型的第一个字母都必须大写。Scala的数据类型有Byte、Short、Int、Long、Float(浮点数后有f或F后缀,否则认为是Double)、Double、Char、String、Boolean、Unit(similar to “void” in java)、Null 、Nothing、Any和AnyRef。

Scala会区分不同类型的值,并且会基于使用值的方式来确定其类型,这称为类型推断
定义一个变量:val name: datatype=initialization
因为能推断类型,以变量为例,定义一个变量通常写成 var name = initialization
除正常用法外,Scala还可以通过 “值.运算符(参数)” 的方式使用运算符,这就应证了前面所说的Scala每个值都是对象。

scala的函数可以不需要return关键字来指明返回值。

Scala操作练习

package ScalaTest

object ScalaTest{

  //变量、常量操作练习
  def ConVarTest(): Unit = {
    var str1 = "I am a String."
    val str2 = "I am a String,too. But I am a constant."
    var str3:String = "I am also a String.And I am generated by a full define sentence."
    val num:Float = 2.4f
    println(str1);  println(str2);  println(str3);  println(num)//scala不需要用分号作为语句的结束,除非一行中有多条语句。
  }

  //数组操作练习
  def ArrTest(): Unit = {
    var arr1:Array[String] = new Array[String](3)
    var arr2:Array[String] = Array[String]("white cloud",", I"," love"," you!")
    println(arr1);  println(arr1(0)); println(arr2(2)); println(arr1.isEmpty)
    //给arr1第一个元素赋值,赋值前是 null
    arr1(0) = "My favorite singer is Faye Wong."
    println(arr1(0)); println(arr2.length); println(arr2.tail);
    println(arr1.isEmpty);  println(arr1.contains("Faye"),arr1(0).contains("Faye"))
    println(arr1 ++ arr2)
    //import Array._ 后,可使用concat方法合并数组,也可使用range方法创建区间数组(默认创建不可变数组,除非导入包)
    import Array._
    val arr3 = range(1,10,2)//1,3,5,7,9
    println(arr3(3))
    val arr4 = concat(arr1,arr2)
    println(arr4(3))//arr4(3)==arr2(0)
  }

  //使用return的函数
  def max1(x:Int,y:Int): Int = {
    if(x>=y)
      return x
    else return y
  }

  //不使用return的函数
  def add(x:Int,y:Int): Int = {x+y}

  def max2(x:Int,y:Int): Int = {
    if(x>=y) x else y
  }

  //List,Set,Map基本知识
  def List_Set_MapTest():Unit = {
    // Scala列表与数组非常相似,列表的所有元素都具有相同的类型。与数组不同的是,列表的元素不能通过赋值来更改。
    //构造列表的两个基本单位是 "Nil""::"; 前者可以表示空列表,后者称为中缀操作符。
    // ":::"".:::"可以将两个列表连接起来,例如 a:::b,b列表的元素被加在a元素的后面,值得注意的是".:::"与之相反。
    //列表也提供了许多方法,例如 List.concat()方法可将两列表连接起来,这里不再示例更多方法。
    val proverb:List[String] = "No" :: "pains" :: "no" :: "gains" :: Nil
    val today:List[Int] = 2020 :: 3 :: 4 :: Nil
    val empty:List[Nothing] = Nil //Nothing也是Scala的一种数据类型
    println(proverb); println(today); println(empty)
    //从上面示例可看出,scala中列表的 ::作用类似于Java中字符串的连接符 +,可以把元素连接起来。
    // Nil类似于c语言中字符数组的"\0"的作用,表示结束。

    //Scala的Set的定义和我们在Python,Java等语言熟知的集合概念相同,默认创建的是不可变集合(除非导入特定包)。
    // Set的方法和 List用法相同,也不再赘述。
    //与列表不同的是,合并两个集合用的是 "++"方法,注意,这是一个方法而不是操作符。
    val set1:Set[String] = Set("MicroSoft","Google","Tencent","Alibaba")
    val set2:Set[String] = Set("武汉","加油")
    println(set1); println(set2); println(set1.++(set2))

    //Map概念同样和我们熟知的编程语言相同。声明和部分方法的示例如下。
    val age:Map[String,Int] = Map("王天霸"->32,"孙悟空"->3600,"陆小千"->25,"游所为"->36)
    println(age.keys);  println(age.values);  println(age)

    //元组类似于列表。与列表不同的是,元组可包含不同类型的元素。
    // 值得注意的是Scala支持的元组最大长度为22,即元组最多有22个元素。
    //声明和索引(下标从1开始)示例如下。
    val t = ("我今年",18,"岁了。")
    println(t); println(t._1)

  }

  def main(args: Array[String]): Unit = {
    ConVarTest()
    ArrTest()
    println(max1(3,5),max2(6,9),add(-54,89))

    //匿名函数。与一般函数相比,它定义时不需要用def声明,也不需要函数名,
    //返回类型和函数体之间用"=>"连接而不是"=",函数体是一个不用加花括号的表达式。
    //定义格式形如: 参数列表=>表达式
    //通常将匿名函数赋值给一个常量或变量,然后通过常量名或变量名调用该函数
    val lambdaFunction1 = (x:Int,y:Int) => x/y
    println(lambdaFunction1(8,4))

    //高阶函数就是操作其他函数的函数。高阶函数可以使用函数作为参数,也可以使用函数作为输出结果。

    //使用函数作为参数示例
    def highOrderFunction1(f: Double => Double) = f(10)
    def minus7(x: Double) = x - 7
    val result2 = highOrderFunction1(minus7)
    println(result2)

    //使用函数作为输出结果示例
    def minusxy(x: Int) = (y: Int) => x - y
    val result3 = minusxy(3)(5)
    println(result3)

    //scala的 if判断与c语言语法规则相同,略

    //scala循环语句。和其他编程语言一样有 while/do...while/for三类循环。下面以最常见的 for举例。
    //for循环语法: for(循环变量 <- 区间){循环语句块}
    //其中区间用 "a to b""a until b"表示。二者区别可见示例。
    for (i <-1 to 10){
      print(i + " ")
      if(i==10) println("")
    }
    for (i <-1 until 10){
      print(i + " ")
      if(i==9) println("")
    }
    //Scala还可以在for循环中使用if判断语句过滤一些元素,多个过滤条件用分号分隔开。
    for (i <-1 to 10;if i%2 == 0;if i <= 6){
      print(i + " ")
    }
    //for循环使用 yield可以将返回值作为一个变量存储,语法格式如下所示。
    val retVar = for (i <-1 to 10;if i%2 == 0;if i <= 6) yield i
    println("\n"+retVar)

    List_Set_MapTest()
  }
}

输出结果:
在这里插入图片描述

Scala课后小练习:

package scalaTest

object scalaWork {
  //定义一个gcd函数,计算两个数的最大公因数
  def gcd(x:Int,y:Int):Int={
    if(x % y == 0) y
    else gcd(x,x % y)
  }
  //sum1函数计算指定区间的值的和
  def sum1(a:Int,b:Int):Int = {
    var sum = 0
    for (i <- a to b){
      sum = sum + i
    }
    sum
  }
  //sum2函数计算指定区间的值的平方的和
  def sum2(a:Int,b:Int):Int = {
    var sum = 0
    for (i <- a to b){
      sum = sum + i * i
    }
    sum
  }
  //sum3函数计算指定区间的值的立方的和
  def sum3(a:Int,b:Int):Int = {
    var sum = 0
    for (i <- a to b){
      sum = sum + i * i * i
    }
    sum
  }
  //返回杨辉三角第 i行第 j列数字。(行和列均从1开始)
  def YangHuiTri(i:Int,j:Int):Int = {
    if(i >= 1 && j >= 1 && j <= i){
      if(j == 1 || j == i)  1
      else YangHuiTri(i - 1,j - 1) + YangHuiTri(i - 1,j)
    }
    else 0  //对异常的输入参数返回0
  }
  //打印杨辉三角
  def printYangHuiTri(N:Int):Unit = {
    for(i <- 1 to N){
      for(j <- 1 to i){
        for(k <- 1 to N-i;if j==1)  print(" ")//打印每行第一个数字前的空格
        print(YangHuiTri(i,j))//打印第 i行第 j列数字
        print(" ")//每个数字后打印一个空格
      }
      print("\n")
    }
  }

  def main(args: Array[String]): Unit = {
    println(gcd(24,12));
    println(sum1(1,4)); println(sum2(1,4)); println(sum3(1,4))
    //打印杨辉三角
    printYangHuiTri(7)
  }
}

小练习输出结果:

在这里插入图片描述

纠正和补充

Scala是函数式语言,Scala将最后出现的变量作为return的值。
使用return必须显式指定返回类型,使Scala失去推断返回值类型的能力,也会使代码看起来不简洁。在编写函数时能不用return就尽量不要使用。
笔记中没有提到如何定义函数,单纯地用语言描绘是不方便的,但如果非要的话——def 函数名(参数1:数据类型,参数2:数据类型,…):函数返回值 = {函数块}
就是上方的模版了。
还有对象和类的概念,虽然没有了解,但是可以先用着(上面的操作练习和小作业中就用了对象Object)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值