scala之旅-核心语言特性【基础】(二)

本章将介绍scala语言的基础内容

尝试在浏览器中使用Scala

你可以使用ScalaFiddle在浏览器中运行Scala。这是一种简单、零基础的方式来实验Scala代码段。

  1. 访问网址 https://scalafiddle.io.
  2. 复制
    println("Hello, world!")

    进左边的面板

  3. 点击Run. 在右边的面板就会显示输出

表达式

表达式是可以被计算的语句:

1+1

你可以用 println 对表达式的结果输出:

println(1) // 1
println(1 + 1) // 2
println("Hello!") // Hello!
println("Hello," + " world!") // Hello, world!

【注:输出结果:】

1
2
Hello
Hello, world

你可以用关键字 val 来命名表达式的结果

val x = 1 + 1
println(x) //2

【注:输出结果:】

2

像 x 这种用来命名结果的,我们称之为值。引用值不会重新计算表达式。

值不能被重新定义赋值. 【注:val修饰的变量是被final修饰过了】

x = 3 // 无法编译通过.

值的类型描述可以被省略,编译器会自行推断出来。当然也可以显式地声明出来

val x: Int = 1 + 1

注意声明类型时,Int是跟在命名 x 后的,用一个 : 表示这个值的类型

变量

变量跟值类似,但是变量可以重新赋值定义。你可以通过 var 关键字来声明一个变量

var x = 1 + 1
x = 3 // 这里因为用var声明,所以可以编译通过    .
println(x * x) // 9

跟值一样,变量的类型也可以被省略或者被推断,也可以被显式的指定出来

var x: Int = 1 + 1

【注:这里解释下 scala是一个静态语言,静态语言意味着变量一旦类型定下就不可以改变。虽然变量和值都是可以通过编译器进行类型推断的,但是类型是不能被修改的。例如:

var a = 10  //变量a 是Int类型,这是编译器推断的结果
a = "hello"  //这里编译会报错,因为a的类型已经是Int,再重新赋予字符串时就会类型错误

代码块

你可以通过 {} 包围的方式来组合表达式。我们称之为代码块。

该块的最后一个表达式的结果也是这个代码块的最终结果:

println({
  val x = 1 + 1
  x + 1
}) // 3

函数

函数是具有参数、并且能传递参数值的表达式。

你可以定义一个匿名函数(例如 一个没有名称的函数),这个函数的作用是给一个整型的值加1

(x: Int) => x + 1

在 => 左边是一个参数的列表,右边则是一个包含参数的表达式

当然你也可以命名这个函数

val addOne = (x: Int) => x + 1
println(addOne(1)) // 2

一个函数可以有多个参数:

val add = (x: Int, y: Int) => x + y
println(add(1, 2)) // 3

当然它也可以没有参数:

val getTheAnswer = () => 42
println(getTheAnswer()) // 42

方法

方法外观和行为都非常像函数,但是它们之间有一些细微的区别。

方法是通过 def 关键字定义, def 后面跟着一个名字,然后紧接着一个参数列表,一个返回结果,和一个代码体

def add(x: Int, y: Int): Int = x + y
println(add(1, 2)) // 3

注意方法的返回类型声明是在参数列表后面用一个 : 接起来的

一个方法可以传递多个参数列表:

def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier
println(addThenMultiply(1, 2)(3)) // 9

或者根本就没有参数列表:

def name: String = System.getProperty("user.name")
println("Hello, " + name + "!")

方法和函数还有一些其他区别,但是就目前为止,你还是可以认为方法就是类似于函数的东西。

方法也可以有多行的表达式:

def getSquareString(input: Double): String = {
  val square = input * input
  square.toString
}
println(getSquareString(2.5)) // 6.25

方法的代码体内的最后一行表达式的结果也就是方法的返回结果.(Scala有返回关键字,但是用的很少) 【注:函数和方法的都是以最后一个变量或表达式作返回结果,你可以认为就是在最后一行代码加隐式的加了一个return】

你可以用 class 关键字定义一个类,类后面接一个参数列表 就是它的有参构造类

class Greeter(prefix: String, suffix: String) {
  def greet(name: String): Unit =
    println(prefix + name + suffix)
}

greet 方法的返回结果是 Unit ,这表明这个方法没有任何返回值。 类似于Java和C中的 void。(有一个小区别是,由于Scala的每个表达式都必须返回值,因此Unit实际上也是一个单例的值,只不过这个值是 空(),不包含任何信息的值)

val greeter = new Greeter("Hello, ", "!")
greeter.greet("Scala developer") // Hello, Scala developer!

我们会在后面的章节对类进行一个深入的讲解

Case 类

Scala有一个特殊的类,叫做 case 类。默认的情况下,case类的实例是不可变的,且它们是通过值比较的(区别与普通的类,普通的类是通过引用进行比较的)。这些特性让case 类在模式匹配中非常的有优势。

你可以定义case类通过 case class 关键字声明:

case class Point(x: Int, y: Int)

你也可以不用new关键字就可以实例化一个case类对象

val point = Point(1, 2)
val anotherPoint = Point(1, 2)
val yetAnotherPoint = Point(2, 2)

case 类是通过值进行比较的,而不是通过引用

if (point == anotherPoint) {
  println(point + " and " + anotherPoint + " are the same.")
} else {
  println(point + " and " + anotherPoint + " are different.")
} // Point(1,2) and Point(1,2) are the same.

if (point == yetAnotherPoint) {
  println(point + " and " + yetAnotherPoint + " are the same.")
} else {
  println(point + " and " + yetAnotherPoint + " are different.")
} // Point(1,2) and Point(2,2) are different.

关于case 类还有很多需要介绍,我们会在后面的章节继续深入介绍,相信你会爱上它们的

Objects 伴生对象

Objects 伴生对象是它们自己定义的一个单例实例。你可以把它认为是一个类自身携带的一个单例

你可以用 object 关键字来定一个伴生对象objects

object IdFactory {
  private var counter = 0
  def create(): Int = {
    counter += 1
    counter
  }
}

你可以引用对象的名称来直接访问它的内部

val newId: Int = IdFactory.create()
println(newId) // 1
val newerId: Int = IdFactory.create()
println(newerId) // 2

我们将在后面的章节来详细介绍它

特性 Traits

特性是一个包含某些属性和方法的抽象数据类型。在Scala继承中,一个类只能被允许继承一个其他类,但是它可以被继承多个特性。

你可以通过 trait 关键字来定义特性:

trait Greeter {
  def greet(name: String): Unit
}

特性可以有一个默认的实现:

trait Greeter {
  def greet(name: String): Unit =
    println("Hello, " + name + "!")
}

你可以使用一个 extends 关键字来继承一个特性,并且用 override 关键字来重写它的实现体

class DefaultGreeter extends Greeter

class CustomizableGreeter(prefix: String, postfix: String) extends Greeter {
  override def greet(name: String): Unit = {
    println(prefix + name + postfix)
  }
}

val greeter = new DefaultGreeter()
greeter.greet("Scala developer") // Hello, Scala developer!

val customGreeter = new CustomizableGreeter("How are you, ", "?")
customGreeter.greet("Scala developer") // How are you, Scala developer?

这里的 DefaultGreeter 只继承了一个特性,但实际上它可以继承多个特性。

我们将在后面的章节深入介绍特性

Main 方法

main 方法是Scala程序的入口点。Java虚拟机也需要一个包含一个String数组参数的 main 方法。

使用一个 伴生对象object,你可以像如下这样定义一个main 方法:

object Main {
  def main(args: Array[String]): Unit =
    println("Hello, Scala developer!")
}
原文地址:https://www.cnblogs.com/zhouwenyang/p/13851134.html