1. 使用 val & var 定义变量

Scala 中的变量被分为2种:val 和 var。其含义于 Java 中的 final 关键字类似。

val 等同于被 final 修饰过的变量, 即一旦初始化便不可被重新赋值。

var 等同于未被 final 修饰过的变量,可以被重新赋值。

   def main(args: Array[String]): Unit = {
val x = 1
x = 2 // 编译错误
}
   def main(args: Array[String]): Unit = {
var x = 1
x = 2 // 编译成功
}

与 Java 相同,这里的所谓不变性,是指引用不可变但是引用对象的状态却是可变的。

object Demo {

  def main(args: Array[String]): Unit = {
val a = new A(1)
a.x = 3
println(a.x)
}
} class A(myX: Int) {
var x: Int = myX
}

以上的例子,输出结果为3。

2. 类型推断

可以看出这里有一个很明显的与 Java 不同的地方:在声明变量的时候,没有显式地给出类型

Scala 支持类型推断,就是它能够根据等式右侧的值来推断出这个参数的类型,例如上面的例子,x 的类型就是 scala.Int。

如果这并不是你所希望的 x 类型,例如,你期望初始化一个 Double 类型的,可以这么定义:

val x: Double = 1

需要注意的是,如果只希望声明变量,而不同时对变量进行初始化(一般来说这种情况只存在于定义成员变量),那么就必须显式定义类型,因为没有等式右侧去推测这个参数的实际类型。

abstract class MyClass {
val y: Int
}

3. 强调参数可变性的意义

Scala 之所以使用 val 和 var 来定义参数,主要就是为了在声明变量时,就确定它的可变性。

Scala 推荐能使用 val 的地方就是用 val,这么做的优势有:

  • Scala 是一门支持函数式编程的语言,将变量定义成 val,可以有效地规避/减少函数的副作用。
  • 将成员变量定义成 val,可以保证构造的对象是不可变对象,这个性质在多线程编程中很有用。

关于不可变对象,可以参考《Java 并发编程实战》P38(因为 Scala 是运行在 JVM 平台上的,编译之后本质其实就是 Java 的字节码文件)

当满足以下条件时,独享才是不可变的:

  • 对象创建以后其状态就不能改变。
  • 对象的所有域都是 final 类型的。
  • 对象是正确创建的(在对象创建期间,this 引用没有溢出)。

4. 使用 def 定义函数

我们观察以下函数的定义:

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

定义一个函数包括以下部分:

  • def -> 定义函数的关键字
  • max -> 函数名
  • x: Int, y: Int -> 参数列表
  • Int -> 函数的结果类型
  • if (x > y) x else y -> 函数体

5. 函数的结果类型

由于 Scala 的类型推断机制,函数的结果类型是可以省略的,也就是说没这么定义函数也是可行的:

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

但是,有一种例外,就是递归地函数,必须给出结果类型:

  def factorial(x: Int) = {
require(x >= 0)
if (x > 1) x * factorial(x - 1) else 1 // 编译错误
}

虽然如此,但是一般推荐所有可以被外部访问的函数(等价于 Java 中的 public),都显式地加上结果类型。 

在上面 main 函数的例子中,结果类型 Unit 等价于 Java 中的 Void,表示函数并不会返回有实际意义的结果。

Scala 基础(1)—— 定义变量 & 定义函数的更多相关文章

  1. 【scala】定义变量和函数

    1.定义变量 Scala的变量分为两种,val和var. val跟java的final变量类似,一旦初始化就不能被重新赋值. var类似于java的非final变量,在整个生命周期内var可以被重新赋 ...

  2. scala基础语法(变量,数据类型,函数)

    一:常量与变量 1.常量 2.两种变量定义方式(严格与不严格) 3.Float注意点 3.注意点 变量名后加上: 类型首字母是大写 4.占位符_ 但是需要制定类型 5.scala数据类型 6.其他类型 ...

  3. 『忘了再学』Shell基础 — 11、变量定义的规则和分类

    目录 1.定义变量的规则 2.变量的分类 1.定义变量的规则 在定义变量时,有一些规则需要遵守 变量名称可以由字母.数字和下划线组成,但是不能以数字开头.如果变量名是2name则是错误的. 在Bash ...

  4. spark快速开发之scala基础之5高阶函数,偏函数,闭包

    高阶函数 高阶函数就是将函数作为参数或者返回值的函数. object function { def main(args: Array[String]): Unit = { println(test(f ...

  5. SQL基础系列(3)-变量、函数、存储过程等

    1.    变量 定义变量 DECLARE @a INT 赋值 PRINT @a ) --select 赋值 SELECT @name='zcx' PRINT @name SELECT @name=F ...

  6. GO语言-基础语法:变量定义

    package main import ( "fmt" ) //不在函数内的变量,属于包内的变量.不能使用":="进行定义和赋值 var ( bb = cc = ...

  7. Kotlin基础语法:变量、函数、类、枚举、控制流

    一切都需要从基础学起! 前言: 在Kotlin语言中,没有分号的概念了,也就是每一行代码,都不在需要用分号结束了 点击查看代码 定义 常量:val --相当于java当中的final 变量:var 关 ...

  8. Scala基础篇-01变量,数据类型

    一.Scala变量 共有3种变量修饰符: val: 可变 var: 不可变 lazy val: 第一次应用时才计算 二.Scala的数据类型 1)类型不匹配:高精度数值赋给低精度数据类型. 2)Uni ...

  9. css中定义变量

    css中定义变量 定义变量可分多种情况: 1.定义全局变量 :root { --borderColor: #ccc;} 2.定义某元素下的变量 .look{ --borderColor: #ccc;} ...

随机推荐

  1. 基于Ceph分布式集群实现docker跨主机共享数据卷

    上篇文章介绍了如何使用docker部署Ceph分布式存储集群,本篇在此基础之上,介绍如何基于Ceph分布式存储集群实现docker跨主机共享数据卷. 1.环境准备 在原来的环境基础之上,新增一台cen ...

  2. 并排打印多个图案(C++实现)

    在练习循环控制语句时,经常会遇到一类问题:使用循环控制打印星号(*)来形成各种各样的图案,并强调所有的星号(*)都要用单条的输出语句cout<<"*";来打印. 例如打 ...

  3. HTML语义化的重要性

    语义化标签就是尽量使用有相对应的结构的含义的Html的标签 1.结构更好,更利于搜索引擎的抓取(SEO的优化)和开发人员的维护(可维护性更高,因为结构清晰,so易于阅读). 2.更有利于特殊终端的阅读 ...

  4. SSO 单点登录总结(PHP)

    本篇文章根据个人理解的知识整理汇总,如有不足之处,请大家多多指正. 单点登录(SSO--Single Sign On)的应用是很普遍的,尤其在大型网站系统中,比如百度,登录百度账号和,再转到百度经验. ...

  5. C语言字符篇(一)字符串转换函数

      #include <stdlib.h>   double atof(const char *nptr);  将字符串转换成双精度浮点数 int atoi(const char *npt ...

  6. PTA 7-12(图) 社交网络图中结点的“重要性”计算 最短路

    7-12(图) 社交网络图中结点的“重要性”计算 (30 分) 在社交网络中,个人或单位(结点)之间通过某些关系(边)联系起来.他们受到这些关系的影响,这种影响可以理解为网络中相互连接的结点之间蔓延的 ...

  7. Mplab X IDE 安装DMCI

     DMCI在Mplab 8中是默认安装的,在 Mplab X IDE中是作为插件,默认不安装.   找到     勾选前面的复选框,点击安装

  8. CodeForces 805F Expected diameter of a tree 期望

    题意: 给出一个森林,有若干询问\(u, v\): 从\(u, v\)中所在子树中随机各选一个点连起来,构成一棵新树,求新树直径的期望. 分析: 回顾一下和树的直径有关的东西: 求树的直径 从树的任意 ...

  9. Invalid bound statement (not found): com.up.sell.mapper.system.H5operationMapper.

    springboot + mybatis项目,出现这样的错误原因就是mapper类的名字和xml的id不对应或者是忘记写了,仔细检查一下吧

  10. JAVA中的类

    节选自:http://www.cnblogs.com/dolphin0520/p/3811445.html 1. 成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一 ...