个人随笔
目录
Scala学习之路 (三)Scala的基本使用
2019-12-09 23:33:26

转自:https://www.cnblogs.com/qingyunzong/p/8858234.html

一、Scala概述

scala是一门多范式编程语言,集成了面向对象编程和函数式编程等多种特性。
scala运行在虚拟机上,并兼容现有的Java程序。
Scala源代码被编译成java字节码,所以运行在JVM上,并可以调用现有的Java类库。

二、第一个Scala程序

Scala语句末尾的分号可写可不写

HelloScala.scala

  1. object HelloScala {
  2. def main(args: Array[String]): Unit = {
  3. println("Hello Scala")
  4. }
  5. }

运行过程先进行编译

编译之后生成2个文件

运行HelloScala.class

输出结果:Hello Scala

三、Scala的基本语法

1、概述

  1. /**
  2. * Scala基本语法:
  3. * 区分大小写
  4. * 类名首字母大写(MyFirstScalaClass)
  5. * 方法名称第一个字母小写(myMethodName())
  6. * 程序文件名应该与对象名称完全匹配
  7. * def main(args:Array[String]):scala程序从main方法开始处理,程序的入口。
  8. *
  9. * Scala注释:分为多行/**/和单行//
  10. *
  11. * 换行符:Scala是面向行的语言,语句可以用分号(;)结束或换行符(println())
  12. *
  13. * 定义包有两种方法:
  14. * 1package com.ahu
  15. * class HelloScala
  16. * 2package com.ahu{
  17. * class HelloScala
  18. * }
  19. *
  20. * 引用:import java.awt.Color
  21. * 如果想要引入包中的几个成员,可以用selector(选取器):
  22. * import java.awt.{Color,Font}
  23. * // 重命名成员
  24. * import java.util.{HashMap => JavaHashMap}
  25. * // 隐藏成员 默认情况下,Scala 总会引入 java.lang._ 、 scala._ 和 Predef._,所以在使用时都是省去scala.的
  26. * import java.util.{HashMap => _, _} //引入了util包所有成员,但HashMap被隐藏了
  27. */

2、Scala的数据类型

Scala 与 Java有着相同的数据类型,下表列出了 Scala 支持的数据类型:

数据类型 描述
Byte 8位有符号补码整数。数值区间为 -128 到 127
Short 16位有符号补码整数。数值区间为 -32768 到 32767
Int 32位有符号补码整数。数值区间为 -2147483648 到 2147483647
Long 64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807
Float 32位IEEE754单精度浮点数
Double 64位IEEE754单精度浮点数
Char 16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF
String 字符序列
Boolean true或false
Unit 表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。
Null null 或空引用
Nothing Nothing类型在Scala的类层级的最低端;它是任何其他类型的子类型。
Any Any是所有其他类的超类
AnyRef AnyRef类是Scala里所有引用类(reference class)的基类

Scala多行字符串的表示方式

  1. var str =
  2. """
  3. |第一行
  4. |第二行
  5. |第三行
  6. """.stripMargin
  7. println(str)

3、Scala的变量

  1. object VariableTest {
  2. def main(args: Array[String]) {
  3. //使用val定义的变量值是不可变的,相当于java里用final修饰的变量
  4. val i = 1
  5. //使用var定义的变量是可变的,在Scala中鼓励使用val
  6. var s = "hello"
  7. //Scala编译器会自动推断变量的类型,必要的时候可以指定类型
  8. //变量名在前,类型在后
  9. val str: String = "world"
  10. }
  11. }

总结:

1)数据类型可以指定,也可以不指定,如果不指定,那么就会进行数据类型的推断。
2)如果指定数据类型,数据类型的执行 方式是 在变量名后面写一个冒号,然后写上数据类型。
3)我们的scala里面变量的修饰符一共有两个,一个是var 一个是val,如果是var修饰的变量,那么这个变量的值是可以修改的。如果是val修饰的变量,那么这个变量的值是不可以修改的。

4、Scala访问修饰符

Scala访问修饰符和Java基本一样,分别有private、protected、public。

默认情况下,Scala对象的访问级别是public。

(1)私有成员

用private关键字修饰的成员仅在包含了成员定义的类或对象内部可见。

  1. class Outer {
  2. class Inner{
  3. def start() = println("start")
  4. def end() = println("end")
  5. private def pause() = println("pause")
  6. }
  7. new Inner().start()
  8. new Inner().end()
  9. new Inner().pause()
  10. }

在上面的代码里start和end两个方法被定义为public类型,可以通过任意Inner实例访问;pause被显示定义为private,这样就不能在Inner类外部访问它。

(2)protected

和私有成员类似,Scala的访问控制比Java来说也是稍显严格些。在 Scala中,由protected定义的成员只能由定义该成员和其派生类型访问。而在 Java中,由protected定义的成员可以由同一个包中的其它类型访问。在Scala中,可以通过其它方式来实现这种功能。

  1. package p
  2. {
  3. class Super
  4. {
  5. protected def f(){println("f")}
  6. }
  7. class Sub extends Super
  8. {
  9. f() //OK
  10. }
  11. class Other
  12. {
  13. (new Super).f() //Error:f不可访问
  14. }
  15. }
(3)public

public访问控制为Scala定义的缺省方式,所有没有使用private和 protected修饰的成员(定义的类和方法)都是“公开的”,这样的成员可以在任何地方被访问。Scala不需要使用public来指定“公开访问”修饰符。

注意:Scala中定义的类和方法默认都是public的,但在类中声明的属性默认是private的。

(4)作用保护域

作用域保护:Scala中,访问修饰符可以通过使用限定词强调。
private[x] 或者 protected[x]
private[x]:这个成员除了对[…]中的类或[…]中的包中的类及他们的伴生对象可见外,对其他的类都是private。

  1. package bobsrockets
  2. {
  3. package navigation
  4. {
  5. //如果为private class Navigator,则类Navigator只会对当前包navigation中所有类型可见。
  6. //即private默认省略了[X],X为当前包或者当前类或者当前单例对象。
  7. //private[bobsrockets]则表示将类Navigator从当前包扩展到对bobsrockets包中的所有类型可见。
  8. private[bobsrockets] class Navigator
  9. {
  10. protected[navigation] def useStarChart() {}
  11. class LegOfJourney
  12. {
  13. private[Navigator] val distance = 100
  14. }
  15. private[this] var speed = 200
  16. }
  17. }
  18. package launch
  19. {
  20. import navigation._
  21. object Vehicle
  22. {
  23. //private val guide:表示guide默认被当前单例对象可见。
  24. //private[launch] val guide:表示guide由默认对当前单例对象可见扩展到对launch包中的所有类型可见。
  25. private[launch] val guide = new Navigator
  26. }
  27. }
  28. }

在这个例子中,类Navigator使用 private[bobsrockets] 来修饰,这表示这个类可以被bobsrockets包中所有类型访问,比如通常情况下 Vehicle无法访问私有类型Navigator,但使用包作用域之后,Vechile 中可以访问Navigator。

5、Scala运算符

与Java一样,不过Scala的运算符实际上是一种方法。

6、条件表达式

Scala的的条件表达式比较简洁,例如:

  1. def main(args: Array[String]): Unit = {
  2. val x = 1
  3. //判断x的值,将结果赋给y
  4. val y = if (x > 0) 1 else -1
  5. //打印y的值
  6. println("y=" + y)
  7. //支持混合类型表达式
  8. val z = if (x > 1) 1 else "error"
  9. //打印z的值
  10. println("z=" + z)
  11. //如果缺失else,相当于if (x > 2) 1 else ()
  12. val m = if (x > 2) 1
  13. println("m=" + m)
  14. //在scala中每个表达式都有值,scala中有个Unit类,写做(),相当于Java中的void
  15. val n = if (x > 2) 1 else ()
  16. println("n=" + n)
  17. //if和else if
  18. val k = if (x < 0) 0
  19. else if (x >= 1) 1 else -1
  20. println("k=" + k)
  21. }

总结:
1)if条件表达式它是有返回值的
2)返回值会根据条件表达式的情况会进行自动的数据类型的推断。

7、块表达式

  1. def main(args: Array[String]): Unit = {
  2. val x = 0
  3. val result = {
  4. if(x < 0)
  5. 1
  6. else if(x >= 1)
  7. -1
  8. else
  9. "error"
  10. }
  11. println(result)
  12. }

8、循环

(1)while循环
  1. def main(args: Array[String]): Unit = {
  2. var n = 10
  3. while (n > 0) {
  4. println(n)
  5. n -= 1
  6. }
  7. }

总结:
1)while使用跟java一模一样
2)注意点:在scala里面不支持 i++ i— 等操作,统一写成 i-=1

(2)for循环

在scala中有for循环和while循环,用for循环比较多

for循环语法结构:

  1. for (i <- 表达式/数组/集合)
  1. def main(args: Array[String]): Unit = {
  2. //for(i <- 表达式),表达式1 to 10返回一个Range(区间)
  3. //每次循环将区间中的一个值赋给i
  4. for (i <- 1 to 10)
  5. print(i+"\t")
  6. //for(i <- 数组)
  7. println()
  8. val arr = Array("a", "b", "c")
  9. for (i <- arr)
  10. println(i)
  11. //高级for循环
  12. //每个生成器都可以带一个条件,注意:if前面没有分号
  13. for(i <- 1 to 3; j <- 1 to 3 if i != j)
  14. print((10 * i + j) + " ")
  15. println()
  16. //for推导式:如果for循环的循环体以yield开始,则该循环会构建出一个集合
  17. //每次迭代生成集合中的一个值
  18. val v = for (i <- 1 to 10) yield i * 10
  19. println(v)
  20. }

总结:

1)在scala里面没有运算符,都有的符号其实都是方法。
2)在scala里面没有++ — 的用法
3)for( i <- 表达式/数组/集合)
4)在for循环里面我们是可以添加if表达式
5)有两个特殊表达式需要了解:

  1. To 1 to 3 1 2 3
  2. Until 1 until 3 12

6)如果在使用for循环的时候,for循环的时候我们需要获取,我们可以是使用yield关键字。

9、方法和函数

(1)定义方法

方法的返回值类型可以不写,编译器可以自动推断出来,但是对于递归函数,必须指定返回类型。如果不写等号,代表没有返回值。定义方法用的是def.

  • 若方法没有参数,可以不写,调用方法时若没有参数也可以不写。
(2)定义函数

  • 若函数没有参数,必须写成()
(3)方法和函数的区别

在函数式编程语言中,函数是“头等公民”,它可以像任何其他数据类型一样被传递和操作

  1. object TestScala {
  2. //定义一个方法
  3. //方法m2参数要求是一个函数,函数的参数必须是两个Int类型
  4. //返回值类型也是Int类型
  5. def m1(f:(Int,Int) => Int) : Int = {
  6. f(2,6)
  7. }
  8. //定义一个函数f1,参数是两个Int类型,返回值是一个Int类型
  9. val f1 = (x:Int,y:Int) => x+y
  10. //再定义一个函数f2
  11. val f2 = (m:Int,n:Int) => m*n
  12. //main方法
  13. def main(args: Array[String]): Unit = {
  14. //调用m1方法,并传入f1函数
  15. val r1 = m1(f1)
  16. println("r1="+r1)
  17. //调用m1方法,并传入f2函数
  18. val r2 = m1(f2)
  19. println("r2="+r2)
  20. }
  21. }

结果:

  1. r1=8
  2. r2=12

(4)将方法转换成函数

 433

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2