Scala入门


0x00 Imports

1. 当从一个包中引入多个时,用花括号

import com.twitter.concurrent.{Broker, Offer}

2. 当引入超过 6 个时使,用通配符

import com.twitter.concurrent._

注:不要轻率的使用: 一些包导入了太多的名字

3. 避免不清晰的引入

// 避免
import com.twitter
import concurrent

// 而应该使用明确的引入
import com.twitter.concurrent

0x01 注释

1. 单行注释

// 我是注释内容👨

2. 多行注释

/**
  * 注释内容😃
  * ...
  */

0x02 数据类型

1. 基本数据类型

数据类型 描述
Byte 8bit(1 字节)有符号数字,范围在-128 到 127
Short 16bit(2 字节)有符号数字,范围在-32768 到 32767
Int 32bit(4 字节)有符号数字,范围在-2147483648 到 2147483647
Long 64bit(8 字节)有符号数字,范围在-9223372036854775808 到 9223372036854775807
Float 32bit(4 字节),IEEE 754 标准的单精度浮点数
Double 64bit(4 字节),IEEE 754 标准的双精度浮点数
Char 16bit Unicode 字符,范围在 U+0000 到 U+FFFF
String 字符串
Boolean 布尔类型
Unit 表示无值,和 Java 中 void 等同。用作不返回任何结果的方法的结果类型。Unit 只有一个实例值,写成()
Null 空值或空引用,唯一实例是 null,AnyRef 的子类
Nothing Nothing 类型在 Scala 的类层级的最低端;它是任何其他类型的子类型,表示没有值,没有实例
Option 表示可能存在(Some),可能不存在(None)的值
None Option 的两个子类之一,用于安全的函数返回值,比 Null 安全
Some Option 的两个子类之一,表示包装了值
Any 所有其他类的超类
AnyRef 所有引用类(reference class)的超类
AnyVal 所有值类型的超类
Nil 长度为 0 的 List

2. 类型层次结构

image.png
数据类型关系图

3. 类型转换

值类型可以按照下面的方向进行单向转换:
image.png
Demo

val x: Long = 987654321
val y: Float = x  // 9.8765434E8 (note that some precision is lost in this case)

val face: Char = '☺'
val number: Int = face  // 9786

0x03 变量&常量

1. 声明

声明变量

var myVar : String = "Foo"
var myVar : String = "Too"

声明常量__(常量的值不可修改,修改常量程序将会在编译时报错

val myVal : String = "Foo"

2. 类型推断

Scala 编译器通常可以推断出表达式的类型,因此你不必显式地声明它。
如果在没有指明数据类型的情况下声明变量或常量必须要给出其初始值,否则将会报错。

var myVar = 10;
val myVal = "Hello, Scala!";

3. 多个变量声明

val x, y = 100   // x, y 都声明为100

0x04 基本语法

1. 图解 Scala 语法

val name: String = "Scala"
println(s"嗨,我是${name},擅长并发和大数据,以语法简洁而著称。")
println("""我诞生于2001年,读作:"skah-lah"。我的发明人是 Martin Odersky,他是瑞士洛桑联邦
           理工大学教授,顶级编程语言学家。 他曾参与设计了一个原型系统GJ, 最终演变为 Java
           泛型。他还曾受雇于 Sun 公司,编写了 javac 的参考编译器。""")

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

for(i <- 0 to 10 if i % 2 == 0) { println(i) }

val tuple = ("jack", 20)
println(s"tuple: ${tuple}, name: ${tuple._1}, age: ${tuple._2}")

case class User(name: String, age: Int = 20)
val jack = User("jack")
val rose = User("rose", 18)
println(jack, rose)
println(jack.name == "jack", jack == User("jack"))

val lambda = (x: Int, y: Int) => { x + y }

val strings = List("1", "2", "3", "4", "5")
println(strings.map(s => s.toInt).filter(i => i % 2 == 0).mkString(","))
val page = 1
val users = List(jack, rose)
println(users.filter(u => u.age >= 18).sortBy(u => (u.name, u.age)).slice(10*(page -1), 10))
val map = Map("jack" -> 20, "rose" -> 18)
println(map("jack"))

val User(jackName, jackAge) = jack
println(jackName, jackAge)
jack match {
  case User(name, age) if name == "jack" => println(s"jack matched.")
  case other => println(s"Hello, ${other.name}")
}

image.png

0x05 元组

1. 简介

在 Scala 中,元组是一个可以容纳不同类型元素的类,元组是不可变的。
当我们需要从函数返回多个值时,元组会派上用场。

2. 定义

val ingredient = ("Sugar" , 25):Tuple2[String, Int]

3. 访问元素

使用下划线语法访问元组, tuple._n 取出了第 n 个元素(假设有足够多元素)。

println(ingredient._1) // Sugar
println(ingredient._2) // 25

4. 解构元组数据

val ingredient = ("Sugar" , 25):Tuple2[String, Int]
val (name, quantity) = ingredient
println(name) // Sugar
println(quantity) // 25

5. 元组的应用

在 for 表达式中

val numPairs = List((2, 5), (3, -7), (20, 56))
for ((a, b) <- numPairs) {
  println(a * b)
}

0x06 数组

1. 声明

var z:Array[String] = new Array[String](3)
// 或
var z = new Array[String](3)
// 或
var z = Array("Runoob", "Baidu", "Google")

2. 赋值

z(0) = "Runoob"; z(1) = "Baidu"; z(4/2) = "Google"

3. 遍历数组

var myList = Array(1.9, 2.9, 3.4, 3.5)

// 输出所有数组元素
for (x <- myList) {
  println(x)
}

4. 多维数组

定义多维数组

val myMatrix = Array.ofDim[Int](3, 3)

二维数组处理 Demo

import Array._

object Test {
   def main(args: Array[String]) {
      val myMatrix = Array.ofDim[Int](3, 3)

      // 创建矩阵
      for (i <- 0 to 2) {
         for ( j <- 0 to 2) {
            myMatrix(i)(j) = j;
         }
      }

      // 打印二维阵列
      for (i <- 0 to 2) {
         for ( j <- 0 to 2) {
            print(" " + myMatrix(i)(j));
         }
         println();
      }
   }
}

5. 合并数组

可以使用 concat() 方法来合并两个数组, concat() 方法中接受多个数组参数:

import Array._

object Test {
   def main(args: Array[String]) {
      var myList1 = Array(1.9, 2.9, 3.4, 3.5)
      var myList2 = Array(8.9, 7.9, 0.4, 1.5)

      var myList3 =  concat( myList1, myList2)

      // 输出所有数组元素
      for ( x <- myList3 ) {
         println( x )
      }
   }
}

6. 创建区间数组

使用 range() 方法可以生成一个区间范围内的数组, range() 方法最后一个参数为步长,默认为 1:

// 生成10-20,步长为2的数组
var myList1 = range(10, 20, 2)
// 10 12 14 16 18

// 生成10-20,步长为1的数组
var myList2 = range(10, 20)
// 10 11 12 13 14 15 16 17 18 19

0x07 集合

1. 集合的类型

Scala 集合类包括可变的和不可变的集合两大类。可变集合类可以修改,添加,移除一个集合的元素。而不可变集合类永远不会改变。不过,仍然可以模拟添加,移除或更新操作。
image.png

2. 集合的使用

使用可变集合

import scala.collection.mutable

// 定义可变集合
val set = mutable.Set()

使用集合类型缺省的构造函数

val seq = Seq(1, 2, 3)
val set = Set(1, 2, 3)
val map = Map(1->"one", 2->"two", 3->"three")

集合基本操作

方法 描述
head 此方法返回列表的第一个元素
tail 此方法返回由除第一个之外的所有元素组成的列表
isEmpty 如果列表为空,则此方法返回* true ,否则返回 false *

拼接集合
可以使用 ++ 运算符或 Set.++() 方法连接两个或多个集合,但是在添加集合时,它将删除重复的元素。

object Demo {
   def main(args: Array[String]) {
      val fruit1 = Set("apples", "oranges", "pears")
      val fruit2 = Set("mangoes", "banana")

      // use two or more sets with ++ as operator
      var fruit = fruit1 ++ fruit2
      println( "fruit1 ++ fruit2 : " + fruit )

      // use two sets with ++ as method
      fruit = fruit1.++(fruit2)
      println( "fruit1.++(fruit2) : " + fruit )
   }
}

/* 运行结果:
fruit1 ++ fruit2 : Set(banana, apples, mangoes, pears, oranges)
fruit1.++(fruit2) : Set(banana, apples, mangoes, pears, oranges)
*/

集合中查找最大值,最小元素
可以使用 Set.min 方法和 Set.max 方法来分别找出集合中元素的最大值和最小值

object Demo {
   def main(args: Array[String]) {
      val num = Set(5,6,9,20,30,45)

      // find min and max of the elements
      println( "Min element in Set(5,6,9,20,30,45) : " + num.min )
      println( "Max element in Set(5,6,9,20,30,45) : " + num.max )
   }
}

/* 运行结果:
Min element in Set(5,6,9,20,30,45) : 5
Max element in Set(5,6,9,20,30,45) : 45
*/

查找交集值
可以使用 Set.& 或 Set.intersect 方法来查找两个集合之间的交集(相交值)

object Demo {
   def main(args: Array[String]) {
      val num1 = Set(5,6,9,20,30,45)
      val num2 = Set(50,60,9,20,35,55)

      // find common elements between two sets
      println( "num1.&(num2) : " + num1.&(num2) )
      println( "num1.intersect(num2) : " + num1.intersect(num2) )
   }
}

/* 运行结果
num1.&(num2) : Set(20, 9)
num1.intersect(num2) : Set(20, 9)
*/

0x08 字符串操作

1. 常用操作

//字符串去重
"aabbcc".distinct // "abc"

//取前n个字符,如果n大于字符串长度返回原字符串
"abcd".take(10) // "abcd"

//字符串排序
"bcad".sorted // "abcd"

//过滤特定字符
"bcad".filter(_ != 'a') // "bcd"

//类型转换
"true".toBoolean
"123".toInt
"123.0".toDouble

2. 原生字符串

//包含换行的字符串
val s1= """Welcome here.
   Type "HELP" for help!"""

//包含正则表达式的字符串
val regex = """\d+"""

3. 字符串插值

val name = "world"
val msg = s"hello, ${name}" // hello, world

0x09 类和对象

1. 声明类

class Point(xc: Int, yc: Int) {
   var x: Int = xc
   var y: Int = yc

   def move(dx: Int, dy: Int) {
      x = x + dx
      y = y + dy
      println ("x 的坐标点: " + x);
      println ("y 的坐标点: " + y);
   }
}

2. 实例化类

object Test {
   def main(args: Array[String]) {
      val pt = new Point(10, 20);

      // 移到一个新的位置
      pt.move(10, 10);
   }
}

3. 继承

class Point(xc: Int, yc: Int) {
   var x: Int = xc
   var y: Int = yc

   def move(dx: Int, dy: Int) {
      x = x + dx
      y = y + dy
      println ("x 的坐标点: " + x);
      println ("y 的坐标点: " + y);
   }
}

class Location(override val xc: Int, override val yc: Int,
   val zc :Int) extends Point(xc, yc){
   var z: Int = zc

   def move(dx: Int, dy: Int, dz: Int) {
      x = x + dx
      y = y + dy
      z = z + dz
      println ("x 的坐标点 : " + x);
      println ("y 的坐标点 : " + y);
      println ("z 的坐标点 : " + z);
   }
}

4. 重写

class Person {
  var name = ""
  override def toString = getClass.getName + "[name=" + name + "]"
}

class Employee extends Person {
  var salary = 0.0
  override def toString = super.toString + "[salary=" + salary + "]"
}

object Test extends App {
  val fred = new Employee
  fred.name = "Fred"
  fred.salary = 50000
  println(fred)
}

文章作者: Truda
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Truda !
评论
  目录