Scala入门(基础)

本文介绍了Scala编程的基础概念,包括常量和变量的定义、插值表达式的使用、类型转换的方法、输入输出操作、循环结构、数组和元组的处理、类和对象的创建以及模式匹配和异常处理的实现。此外,还讲解了如何使用提取器进行数据提取。
摘要由CSDN通过智能技术生成

Scala编程,类似Java,面向对象

常量和变量

定义方式:

val/var 变量名:变量类型 [= 初始值]

若定义了类型,初始值可省略
若省略类型,则必须有初始值

插值表达式

此方法用来拼接字符串

	val/var 变量名 = s"${变量/表达式}字符串"

转换

自动转换和强制转换
  1. 自动转换是从范围小的类型向范围大的类型转换

  2. 强制转换

val/var 变量名:String = 值类型数据.toXXXX  //XXX表示你要转换到的数据类型
val/var 变量名:值类型 = 字符串值.toXXXX  //XXX表示你要转换到的数据类型

转换成字符串示例

val a1:Int = 10
val b1:Double = 3.6
val c1:Boolean = false
// 类型首字母要大写

//方式一: 通过和空字符串拼接的形式实现
val a2:String = a1 + ""
val b2:String = b1 + ""
val c2:String = c1 + ""

//方式二: 通过toString函数实现
val a3:String = a1.toString
val b3:String = b1.toString
val c3:String = c1.toString

输入输出

  1. 先导入包
 import scala.io.StdIn
// 接收输入
println("请输入字符串: ")
val str = StdIn.readLine()
println("您输入的字符串内容为: " + str)

println("请输入整数: ")
val num = StdIn.readInt()
println("您输入的数字为: " + num)

println("请输入浮点数: ")
val num = StdIn.readFloat()
println("您输入的数字为: " + num)

在这里插入图片描述

循环

while
do…while
for循环有区别

for( var x <- Range ){
   statement(s);
}
object Test {
   def main(args: Array[String]) {
      var a = 0;
      // for 循环
      for( a <- 1 to 10){
         println( "Value of a: " + a );
      }
   }
}

数组

可以指定数据类型也可以不指定,但是数据类型必须保持一致

object TestArray {
  def main(args: Array[String]) {
    /**
     *  数组语法格式
     *  var z:Array[String] = new Array[String](3)
     *    或
     *  var z = new Array[String](3)
     */
    var myList = Array(1.9, 2.9, 3.4, 3.5)

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

    // 计算数组所有元素的总和
    var total = 0.0;
    for ( i <- 0 to (myList.length - 1)) {
      total += myList(i);
    }
    println("总和为 " + total);

    // 查找数组中的最大元素
    var max = myList(0);
    for ( i <- 1 to (myList.length - 1) ) {
      if (myList(i) > max) max = myList(i);
    }
    println("最大值为 " + max);

  }
}

元组

  • new Tuplex( ) , 此处x代表的是元组的长度
  • 目前 Scala 支持的元组最大长度为 22。对于更大长度你可以使用集合,或者扩展元组。
object TestTuple {
  def main(args: Array[String]) {
    val t = new Tuple3(1, "hello", Console)

    println("连接后的字符串为: " + t.toString() )
    // 我们可以使用 t._1 访问第一个元素, t._2 访问第二个元素,如下所示:
    println(t._1)

    // 迭代访问元组
    t.productIterator.foreach{ i =>println("Value = " + i )}
  }
} 

在这里插入图片描述

类和对象

在 Scala 中用 Object 来代替 java 中 static 单例关键字

import java.io._

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);
   }
}

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

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

输出:

x 的坐标点: 20
y 的坐标点: 30

类的构造顺序

class bike (var message: String) 
{ 
    println("I have " + message) 
} 
 
class speeding (message: String) extends bike (message) 
{ 
	println("subclass") 
	
    def display() 
    { 
        println("Bike bike goes Brooom! ") 
    } 
}
 
object MyObject 
{ 
    def main(args: Array[String]) 
    { 
        var newbike = new speeding("Ninja H2R"); 
        newbike.display(); 
    } 
} 

特征也可以有构造器,由字段的初始化和其他特征体中的语句构成。这些语句在任何混入该特征的对象在构造时都会被执行。
构造器的执行顺序:

  • 调用超类的构造器
  • 特征构造器在超类构造器之后、类构造器之前执行;
  • 特征由左到右被构造;
  • 每个特征当中,父特征先被构造;
  • 如果多个特征共有一个父特征,父特征不会被重复构造
  • 所有特征被构造完毕,子类被构造。

Trait(特征)

Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。

与接口不同的是,它还可以定义属性和方法的实现。

一般情况下Scala的类只能够继承单一父类,但是如果是 Trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承。

如果继承多个Trait需要同时使用extends和with关键字

 trait Equal {
  def isEqual(x: Any): Boolean
  def isNotEqual(x: Any): Boolean = !isEqual(x)
}

// 必须实现特性(trait)中所有位实现的抽象方法
class Point(xc: Int, yc: Int) extends Equal {
  var x: Int = xc
  var y: Int = yc
  def isEqual(obj: Any) =
    obj.isInstanceOf[Point] &&
      obj.asInstanceOf[Point].x == x
}

模式匹配(case)

在声明样例类时,下面的过程自动发生了:

  • 构造器的每个参数都成为val,除非显式被声明为var,但是并不推荐这么做;
  • 在伴生对象中提供了apply方法,所以可以不使用new关键字就可构建对象;
  • 提供unapply方法使模式匹配可以工作;
  • 生成toString、equals、hashCode和copy方法,除非显示给出这些方 法的定义。
object Testcase {
  def main(args: Array[String]) {
    println(matchTest("two"))
    println(matchTest("test"))
    println(matchTest(1))
    println(matchTest(6))

  }
  // scala的模式匹配相当于java中的switch,但是只要匹配成功就不会运行后面的代码
  def matchTest(x: Any): Any = x match {
    case 1 => "one"
    case "two" => 2
    case y: Int => "scala.Int"
    case _ => "many"
  }
}

抛出异常

import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException

// 异常捕捉的机制与其他语言中一样,如果有异常发生,catch 字句是按次序捕捉的。
// 因此,在 catch 字句中,越具体的异常越要靠前,越普遍的异常越靠后。
// 如果抛出的异常不在 catch 字句中,该异常则无法处理,会被升级到调用者处。
object TestCatchException {
  def main(args: Array[String]) {
    try {
      val f = new FileReader("input.txt")
    } catch {
      case ex: FileNotFoundException =>{
        println("Missing file exception")
      }
      case ex: IOException => {
        println("IO Exception")
      }
    } finally {
      println("Exiting finally...")
    }
  }
}

Missing file exception
Exiting finally…

提取器

object TestExtractor {
  def main(args: Array[String]) {

    println ("Apply 方法 : " + apply("Zara", "gmail.com"));
    println ("Unapply 方法 : " + unapply("Zara@gmail.com"));
    println ("Unapply 方法 : " + unapply("Zara Ali"));

  }
  // Scala 提取器是一个带有unapply方法的对象。unapply方法算是apply方法的反向操作:
  // unapply接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。
  // 注入方法 (可选)
  def apply(user: String, domain: String) = {
    user +"@"+ domain
  }

  // 提取方法(必选)
  def unapply(str: String): Option[(String, String)] = {
    val parts = str split "@"
    if (parts.length == 2){
      Some(parts(0), parts(1))
    }else{
      None
    }
  }
}

可用来提取邮箱,提取关键字等等
在这里插入图片描述

提取

object TestExtractor {
  def main(args: Array[String]) {

    val x = TestExtractor(5)
    println(x)

    x match
    {
      case TestExtractor(num) => println(x + " 是 " + num + " 的两倍!")
      //unapply 被调用
      case _ => println("无法计算")
    }

  }

  // apply 和 unapply 在进行模式匹配时是关键字!!!
  def apply(x: Int) = x*2
  def unapply(z: Int): Option[Int] = if (z%2==0) Some(z/2) else None
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值