scala(二) 变量与数据类型

2021-06-19  本文已影响0人  万事万物

注释

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

命名规范

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

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 特定的语法

变量

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

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

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

声明变量实例如下:

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

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

val myVal : String = "Foo"

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

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

    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 也是如此

    val i = 10
    val d = 2.3d
    val f = 2.3f
    val s = "hello"
    val c ='a'
    val b = true

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


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


字符串

定义字符串

val str="hello"

字符串的拼接

val str="hello"
val str1="world"
val str2 =str+str1 # helloworld

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

val str2 =str concat(str1) # helloworld

或者简写

val str2 =str concat str1 # helloworld

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

val str2 =s"${str}${str1}" # helloworld

或者简写

val str2 =s"$str$str1" # helloworld

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

val str2 = String.format("%s,%s",str,str1) #hello,world

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

print("********************") # ********************

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

print("*"*20)  # ********************

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

def * (n: Int): String = {
    val buf = new StringBuilder
    for (i <- 0 until n) buf append toString
    buf.toString
}

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

print("*"*20) # 840

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

val str ="hello"
println(str.toUpperCase) # HELLO

转小写

val str ="HELLO"
println(str.toLowerCase) # hello

截取

println(str.substring(0,2)) # he

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

输出打印

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

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

    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依赖

import scala.io.StdIn

接收一个用户输入

  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数据类型
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

案例:

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

结果:

by=10,by的类型=byte
sho=34,sho=short
i=10,i的类型=int
l=1000,by的类型=long

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

var n1:Byte = 127
var n2:Byte = -128

错误

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标准的双精度浮点数

案例:

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

结果

f=10.23,f的类型=float
d=56.25,d的类型=double

字符类型(Char)

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

  1. 字符常量是用单引号 ' ' 括起来的单个字符。
  2. 可以直接给Char赋一个整数,然后输出时,会按照对应的unicode字符输出
  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")
  }

结果:

man=男,f的类型=char
woman=女,woman的类型=char
a的unicode=97
b=b

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

val c ='a'+1
println(c) // 98

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

val c ='a'+1
println(c.toChar) // b

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

符号 字符含义
\n 换行 (0x0a)
\r 回车 (0x0d)
\f 换页符(0x0c)
\b 退格 (0x08)
\0 空字符 (0x0)
\s 空格 (0x20)
\t 制表符
" 双引号
' 单引号
\ 反斜杠
\ddd 八进制字符 (ddd)
\uxxxx 16进制Unicode字符 (xxxx)

布尔类型:Boolean

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

Unit类型、Null类型和Nothing类型

数据类型 描述
Unit 表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。
Null null , Null 类型只有一个实例值null
Nothing Nothing类型在Scala的类层级的最低端;它是任何其他类型的子类型。当一个函数,我们确定没有正常的返回值,可以用Nothing来指定返回类型,这样有一个好处,就是我们可以把返回的值(异常)赋给其它的函数或者变量(兼容性)

数值类型间转换

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


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

  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}")
  }
r=100,r的数据类型为int

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

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

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类型
方式一:(语法:将基本类型的值+"" 即可)

  def main(args: Array[String]): Unit = {
    val i =10
    val r="aa"+i
    println(r) //  aa10
  }

方式二:*.toString

  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

  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++

  def main(args: Array[String]): Unit = {
    var i=0;
    i-=1
    println(i) // -1
  }

i--

  def main(args: Array[String]): Unit = {
    var i=0;
    i+=1
    println(i) // 1
  }

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

    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=多少?

a=10
b=13

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

    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);
    }
a=13
b=7
上一篇下一篇

猜你喜欢

热点阅读