scala(二) 变量与数据类型

2022-04-11 16:04:31 浏览数 (1)

注释

scala 注释 与 java 完全一样 // 单行注释 /*...*/ 多行注释 /**...*/ 文本注释注释

命名规范

Scala中的标识符声明,基本和Java是一致的,但是细节上会有所变化,有以下四种规则: (1)以字母或者下划线开头,后接字母、数字、下划线 (2)以操作符开头,且只包含操作符( - * / # !等) (3)第一种和第二种拼接,第一种在前,二者以下划线分隔 (4)用反引号....包括的任意字符串,即使是关键字(39个)也可以 案例

代码语言:javascript复制
hello    // ok
hello12 // ok
1hello  // error
h-b      // error
x h      // error
h_4      // ok
_ab      // ok
Int      // ok , 因为在Scala Int是预定义的字符,不推荐
Float    // ok 
_        // error ,单独一个下划线不可以作为标识符
Abc      // ok
 *-      // ok
 a       // error
$a       // ok , 但不要让scala的标识符出现$,因为scala编译器会使用$

关键字

scala 关键字scala 关键字

红色:scala 扩展的关键字 蓝色:scala 特定的语法

变量

变量是一种使用方便的占位符,用于引用计算机内存地址,变量创建后会占用一定的内存空间。

基于变量的数据类型,操作系统会进行内存分配并且决定什么将被储存在保留内存中。因此,通过给变量分配不同的数据类型,你可以在这些变量中存储整数,小数或者字母。 变量声明 在学习如何声明变量与常量之前,我们先来了解一些变量与常量。

一、变量: 在程序运行过程中其值可能发生改变的量叫做变量。如:时间,年龄。 二、常量 在程序运行过程中其值不会发生变化的量叫做常量。如:数值 3,字符'A'。 在 Scala 中,使用关键词 "var" 声明变量,使用关键词 "val" 声明常量。

声明变量实例如下:

代码语言:javascript复制
var myVar : String = "Foo"
var myVar : String = "Too"

声明常量实例如下:可以理解java中的以 final 修饰的变量——常量

代码语言:javascript复制
val myVal : String = "Foo"

以 var 修饰变量可以修改,而 val 修饰的变量是一个常量,是不可以变的。 以上来自 菜鸟教程

在scala中是可以不用指定变量类型,能够自动转换。

代码语言:javascript复制
    var i = 10  // Int 
    var d = 2.3d // Double
    var f = 2.3f // Float
    var s = "hello" // String
    var c ='a' // Char
    var b = true // Boolean

使用 val 也是如此

代码语言:javascript复制
    val i = 10
    val d = 2.3d
    val f = 2.3f
    val s = "hello"
    val c ='a'
    val b = true

也许这样,看不出来,此图(来自idea)

最后:官方推荐使用 val 修饰而不是 var。


字符串

定义字符串

代码语言:javascript复制
val str="hello"

字符串的拼接

代码语言:javascript复制
val str="hello"
val str1="world"
val str2 =str str1 # helloworld

也可以使用 到java中的 的方法

代码语言:javascript复制
val str2 =str concat(str1) # helloworld

或者简写

代码语言:javascript复制
val str2 =str concat str1 # helloworld

以上两种方式都算是java的方式,那 scala 有什么方式呢?在scala支持 插值写入 的方式,该方式类似于 java中的 format。 语法:s"${}"

代码语言:javascript复制
val str2 =s"${str}${str1}" # helloworld

或者简写

代码语言:javascript复制
val str2 =s"$str$str1" # helloworld

既然类似于 java中的 format,那么在java中这里也是可以使用的 %s 表示字符串,除了%s,还有%d、%c 等;需要了解到童鞋可以看看这篇博客常规类型的格式化

代码语言:javascript复制
val str2 = String.format("%s,%s",str,str1) #hello,world

字符串乘积输出;思考如何在控制台输出20个*? 方式一:

代码语言:javascript复制
print("********************") # ********************

这种方式,优点费时,若是一万个 *呢?当然你也可以编写函数,比如使用StringBuilder。 在scala中有更优雅更简单的方式

代码语言:javascript复制
print("*"*20)  # ********************

其实scala底层源码就是采用StringBuilder实现的

代码语言:javascript复制
def * (n: Int): String = {
    val buf = new StringBuilder
    for (i <- 0 until n) buf append toString
    buf.toString
}

千万不要使用 单引号('')包括,否则会转换成unicode码 进行相乘。

代码语言:javascript复制
print("*"*20) # 840

只有 scala 中的 字符串相关的方法,大部分都可使用 Java自带的。 转大写

代码语言:javascript复制
val str ="hello"
println(str.toUpperCase) # HELLO

转小写

代码语言:javascript复制
val str ="HELLO"
println(str.toLowerCase) # hello

截取

代码语言:javascript复制
println(str.substring(0,2)) # he

关于其他方法就不写了,可以自行了解

输出打印

用于将结果打印到控制台,如同java中的System.out.println() 在scala中有三种输出打印方法

  • println() :打印换行
  • print() :打印不换行
  • printf() :支持格式化打印

关于println()print() 就不讲了,很好理解;这里说一下 printf(),可以用于格式化输出。

代码语言:javascript复制
    val i =1
    val n1="小明"
    val n2 ="小刚"
    val d =5.3d

    printf("%s花了%.2f钱,买了%d个苹果给%s",n1,d,i,n2) # 小明花了5.30钱,买了1个苹果给小刚

键盘输入

在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。 StdIn.readLine()、StdIn.readShort()、StdIn.readDouble()... 引入StdIn依赖

代码语言:javascript复制
import scala.io.StdIn

接收一个用户输入

代码语言:javascript复制
  def main(args: Array[String]): Unit = {
    print("请输入你的姓名:")
    val r=StdIn.readLine()
    print(s"你好;${r}同学")
  }
// 请输入你的姓名:张三
// 你好;张三同学

除了 readLine 方法,还包含:

方法

参数值

readLine

# 接收字符串

readBoolean

# 接收布尔类型

readByte

# 接收 Byte类型

readShort

# 接收 Short类型

readChar

# 接收 Char 类型

readInt

# 接收 Int 类型

readLong

# 接收 Long 类型

readFloat

# 接收 Float 类型

readDouble

# 接收 Double 类型


数据类型关系

scala数据类型scala数据类型

AnyVal:数值类型 AnyRef:引用类型

StringOps:Scala 中对Java中的String增强

Unit:对应 Java中的void,用于方法返回值的位置,表示方法没有返回值。Unit是一个数据类型。只有一个对象就是()。void 不是数据类型,只是一个关键字。

Null:是一个类型,只有一个对象就是null。它是所有引用类型的(AnyRef)的子类

Nothing:是所有数据类型的子类,主要用在一个函数没有明确返回值时使用,因为这样我们可以把抛出的返回值,返回给任何的变量或者函数。


整数类型(Byte、Short、Int、Long)

Scala的整数类型就是用于存放整数值的,比如12,30,3456等等

数据类型

描述

Byte [1]

8位有符号补码整数。数值区间为 -128 到 127

Short [2]

16位有符号补码整数。数值区间为 -32768 到 32767

Int [4]

32位有符号补码整数。数值区间为 -2147483648 到 2147483647

Long [8]

64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807 = 2的(64-1)次方-1

案例:

代码语言:javascript复制
  def main(args: Array[String]): Unit = {
    val by:Byte =10
    val sho:Short =34
    val i =10
    val l =1000L
    println(s"by=$by,by的类型=${by.getClass.getSimpleName}")
    println(s"sho=$sho,sho=${sho.getClass.getSimpleName}")
    println(s"i=$i,i的类型=${i.getClass.getSimpleName}")
    println(s"l=$l,by的类型=${l.getClass.getSimpleName}")
  }

结果:

代码语言:javascript复制
by=10,by的类型=byte
sho=34,sho=short
i=10,i的类型=int
l=1000,by的类型=long

当然每种类型不能超过自己的作用范围;例如 byte 正确

代码语言:javascript复制
var n1:Byte = 127
var n2:Byte = -128

错误

代码语言:javascript复制
var n3:Byte = 128
var n4:Byte = -129

浮点类型(Float、Double)

Scala的浮点类型可以表示一个小数,比如123.4f,7.8,0.12等等。

数据类型

描述

Float [4]

32 位, IEEE 754标准的单精度浮点数

Double [8]

64位 IEEE 754标准的双精度浮点数

案例:

代码语言:javascript复制
  def main(args: Array[String]): Unit = {
    val f =10.23f
    val d =56.25d
    println(s"f=$f,f的类型=${f.getClass.getSimpleName}")
    println(s"d=$d,d的类型=${d.getClass.getSimpleName}")
  }

结果

代码语言:javascript复制
f=10.23,f的类型=float
d=56.25,d的类型=double

字符类型(Char)

字符类型可以表示单个字符,字符类型是Char,16位无符号Unicode字符(2个字节),区间值为U 0000到U FFFF。 案例

  1. 字符常量是用单引号 ' ' 括起来的单个字符。
  2. 可以直接给Char赋一个整数,然后输出时,会按照对应的unicode字符输出
代码语言:javascript复制
  def main(args: Array[String]): Unit = {
    val man ='男'
    val woman ='女'
    val a ='a'
    val b:Char=98
    println(s"man=$man,f的类型=${man.getClass.getSimpleName}")
    println(s"woman=$woman,woman的类型=${woman.getClass.getSimpleName}")
    println(s"a的unicode=${a.toInt}")
    println(s"b=$b")
  }

结果:

代码语言:javascript复制
man=男,f的类型=char
woman=女,woman的类型=char
a的unicode=97
b=b

在 java 可以实现 char 与 int 相加;char自动转为 int(隐式转换);在scala也是可以的。

代码语言:javascript复制
val c ='a' 1
println(c) // 98

若要把int 转为 char 那么需要强制,在scala 中不能使用(类型)的方式,而是需要用到 前面有介绍的 toXXX 函数

代码语言:javascript复制
val c ='a' 1
println(c.toChar) // b

除了这些外,还支持转义字符;如下

符号

字符含义

n

换行 (0x0a)

r

回车 (0x0d)

f

换页符(0x0c)

b

退格 (0x08)

空字符 (0x0)

s

空格 (0x20)

t

制表符

"

双引号

'

单引号

反斜杠

ddd

八进制字符 (ddd)

uxxxx

16进制Unicode字符 (xxxx)


布尔类型:Boolean

  1. 布尔类型也叫Boolean类型,Booolean类型数据只允许取值true和false
  2. boolean类型占1个字节。
代码语言:javascript复制
  val bool1=true
  val bool2:Boolean=false

Unit类型、Null类型和Nothing类型

数据类型

描述

Unit

表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。

Null

null , Null 类型只有一个实例值null

Nothing

Nothing类型在Scala的类层级的最低端;它是任何其他类型的子类型。当一个函数,我们确定没有正常的返回值,可以用Nothing来指定返回类型,这样有一个好处,就是我们可以把返回的值(异常)赋给其它的函数或者变量(兼容性)

  • Null类只有一个实例对象,Null类似于Java中的null引用。Null可以赋值给任意引用类型(AnyRef),但是不能赋值给值类型(AnyVal)
  • Unit类型用来标识过程,也就是没有明确返回值的函数。 由此可见,Unit类似于Java里的void。Unit只有一个实例——( ),这个实例也没有实质意义
  • Nothing,可以作为没有正常返回值的方法的返回类型,非常直观的告诉你这个方法不会正常返回,而且由于Nothing是其他任意类型的子类,他还能跟要求返回值的方法兼容。

数值类型间转换

数值类型自动转换 当Scala程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数值类型,这个就是自动类型转换(隐式转换)。数据类型按精度(容量)大小排序为:

(1)自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成精度大的那种数据类型,然后再进行计算。 (2)当我们把精度大的数值类型赋值给精度小的数值类型时,就会报错,反之就会进行自动类型转换。

代码语言:javascript复制
def main(args: Array[String]): Unit = {
    val i:Int =10
    val l:Long=200
    val r =i l
    println(s"r=$r,r的数据类型为${r.getClass.getSimpleName}") // r=210,r的数据类型为long
  }
代码语言:javascript复制
def main(args: Array[String]): Unit = {
    val i:Int =10
    val l:Long=200
    val d:Double=56.23
    val r =i l d
    println(s"r=$r,r的数据类型为${r.getClass.getSimpleName}") // r=266.23,r的数据类型为double
  }

(3)(byte,short)和char之间不会相互自动转换。 (4)byte,short,char他们三者可以计算,在计算时首先转换为int类型。

代码语言:javascript复制
  def main(args: Array[String]): Unit = {
    val b:Byte =1
    val s:Short=2
    val c:Char='a'
    val r =b s c
    println(s"r=$r,r的数据类型为${r.getClass.getSimpleName}")
  }
代码语言:javascript复制
r=100,r的数据类型为int

强制类型转换 在java中强制转换需要使用(类型)的方式,scala中不支持这样操作,若需要强制转换那么就要使用到toXXX函数

自动类型转换的逆过程,将精度大的数值类型转换为精度小的数值类型。使用时要加上强制转函数,但可能造成精度降低或溢出,格外要注意。

代码语言:javascript复制
def main(args: Array[String]): Unit = {
    val i:Int =10
    val d:Double=56.23

    val ii=i.toDouble
    val dd=d.toInt
    println(s"ii=$ii,ii的数据类型为${ii.getClass.getSimpleName}")  // ii=10.0,ii的数据类型为double
    println(s"dd=$dd,dd的数据类型为${dd.getClass.getSimpleName}") // dd=56,dd的数据类型为int
  }

上面有演示 Char类型可以保存Int的常量值,但不能保存Int的变量值,需要强转 Byte和Short类型在进行运算时,当做Int类型处理。


数值类型和String类型间转换

在程序开发中,我们经常需要将基本数值类型转成String类型。或者将String类型转成基本数值类型。

基本类型转String类型 方式一:(语法:将基本类型的值 "" 即可)

代码语言:javascript复制
  def main(args: Array[String]): Unit = {
    val i =10
    val r="aa" i
    println(r) //  aa10
  }

方式二:*.toString

代码语言:javascript复制
  def main(args: Array[String]): Unit = {

    val i=65
    val ii=i.toString
    println(s"ii=$ii,ii的数据类型为${ii.getClass.getSimpleName}") // ii=65,ii的数据类型为String
  }

String类型转基本数值类型(语法:s1.toInt、s1.toFloat、s1.toDouble、s1.toByte、s1.toLong、s1.toShort) 如:字符串转 Double

代码语言:javascript复制
  def main(args: Array[String]): Unit = {
    val s1="52.36"
    val ii=s1.toDouble
    println(s"ii=$ii,ii的数据类型为${ii.getClass.getSimpleName}") //ii=52.36,ii的数据类型为double
  }

注意: 在将String类型转成基本数值类型时,要确保String类型能够转成有效的数据,比如我们可以把"123",转成一个整数,但是不能把"hello"转成一个整数。


运算符

算术运算符

运算符

运算

范例

结果

正号

3

3

-

负号

b=4;

-b -4

5 5

10

-

6-4

2

*

3*4

12

/

5/5

1

%

取模(取余)

7%5

2

字符串相加

“He” ”llo”

“Hello”

(1)对于除号“/”,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。 (2)对一个数取模a%b,和Java的取模规则一样 关系运算符(比较运算符)

运算符

运算

范例

结果

==

相等于

4==3

false

!=

不等于

4!=3

true

<

小于

4<3

false

>

大于

4>3

true

<=

小于等于

4<=3

false

>=

大于等于

4>=3

true

逻辑运算符 用于连接多个条件(一般来讲就是关系表达式),最终的结果也是一个Boolean值。 假定:变量A为true,B为false

运算符

描述

实例

&&

逻辑与

(A && B) 运算结果为 false

||

逻辑或

(A || B) 运算结果为 true

!

逻辑非

!(A && B) 运算结果为 true

赋值运算符 赋值运算符就是将某个运算后的值,赋给指定的变量。

运算符

描述

实例

=

简单的赋值运算符,将一个表达式的值赋给一个左值

C = A B 将 A B 表达式结果赋值给 C

=

相加后再赋值

C = A 等于 C = C A

-=

相减后再赋值

C -= A 等于 C = C - A

*=

相乘后再赋值

C *= A 等于 C = C * A

/=

相除后再赋值

C /= A 等于 C = C / A

%=

求余后再赋值

C %= A 等于 C = C % A

<<=

左移后赋值

C <<= 2 等于 C = C << 2

>>=

右移后赋值

C >>= 2 等于 C = C >> 2

&=

按位与后赋值

C &= 2 等于 C = C & 2

^=

按位异或后赋值

C ^= 2 等于 C = C ^ 2

|=

按位或后赋值

C |= 2 等于 C = C | 2

注意:Scala中没有 、--操作符,需要通过 =、-=来实现同样的效果 位运算符

运算符

描述

实例

&

按位与运算符

(a & b) 输出结果 12 ,二进制解释: 0000 1100

|

按位或运算符

(a | b) 输出结果 61 ,二进制解释: 0011 1101

^

按位异或运算符

(a ^ b) 输出结果 49 ,二进制解释: 0011 0001

~

按位取反运算符

(~a ) 输出结果 -61 ,二进制解释: 1100 0011, 在一个有符号二进制数的补码形式。

<<

左移动运算符

a << 2 输出结果 240 ,二进制解释: 1111 0000

>>

右移动运算符

a >> 2 输出结果 15 ,二进制解释: 0000 1111

>>>

无符号右移

A >>>2 输出结果 15, 二进制解释: 0000 1111

scala 中实现 i 及 i-- 操作

i

代码语言:javascript复制
  def main(args: Array[String]): Unit = {
    var i=0;
    i-=1
    println(i) // -1
  }

i--

代码语言:javascript复制
  def main(args: Array[String]): Unit = {
    var i=0;
    i =1
    println(i) // 1
  }

至于为什么 scala 不支持 i 及 i--;大部分网友说,开发者认为i ,i-- 可读性太差,理解起来不好。 比如:

代码语言:javascript复制
    public static void main(String[] args) {
       int a=10;
       a=a  ;
       a=a  ;
       a=a  ;
       System.out.println("a=" a);

       int b=10;
       b=  b;
       b=  b;
       b=  b;
       System.out.println("b=" b);
    }

思考一下,a=多少?b=多少?

代码语言:javascript复制
a=10
b=13

i =,i-= 的方式;理解起来就会简单很多

代码语言:javascript复制
    public static void main(String[] args) {
       int a=10;
       a =1;
       a =1;
       a =1;
       System.out.println("a=" a);

       int b=10;
       b-=1;
       b-=1;
       b-=1;
       System.out.println("b=" b);
    }
代码语言:javascript复制
a=13
b=7

0 人点赞