在Java中,您可以这样声明新变量:
String s = "hello";
int i = 42;
Person p = new Person("Joel Fleischman");
每个变量声明之前都有其类型。
相比之下,Scala具有两种类型的变量:
val
创建一个不可变量(例如final
在Java中)也就是常量var
创建一个可变变量这是Scala中的变量声明:
val s = "hello" // immutable 不可变
var i = 42 // mutable 可变
val p = new Person("Joel Fleischman")
这些示例表明,Scala编译器通常很聪明,可以从符号右侧的代码推断出变量的数据类型=
。我们说变量的类型是由编译器推断的。如果愿意,还可以显式声明变量类型:
val s: String = "hello"
var i: Int = 42
在大多数情况下,编译器不需要查看那些显式类型,但是如果您认为它们使代码更易于阅读,则可以添加它们。
实际上,当您使用第三方库中的方法时,有助于显式显示类型,特别是如果您不经常使用该库,或者如果它们的方法名称不能使类型明确的话。
val
和var
之间的区别val
和之间的区别var
是,val
使变量不变(就像final
Java中一样),var
并使变量可变。由于val
字段不能改变,因此有些人将其称为值而不是变量。
REPL显示当您尝试重新分配val
字段时会发生什么:
这了 reassignment 是再赋值的意思。
scala> val a = 'a'
a: Char = a
scala> a = 'b'
<console>:12: error: reassignment to val
a = 'b'
^
正如预期的那样,此操作失败并显示“ val的重新分配”错误。相反,您可以重新分配var
:
scala> var a = 'a'
a: Char = a
scala> a = 'b'
a: Char = b
在Scala中,一般规则是,val
除非有充分的理由不这样做,否则应始终使用字段。这个简单的规则
这是带有val
字段的“ Hello,world”应用程序的外观:
object Hello3 extends App {
val hello = "Hello, world"
println(hello)
}
像之前一样:
scalac Hello3.scala
scala Hello3
val
REPL中的字段的注释REPL与在IDE中处理源代码并不完全相同,因此在REPL中您可以做一些事情,而在项目中实际代码时是做不到。
但是您可以val
在REPL中重新定义字段,如下所示:
scala> val age = 18
age: Int = 18
scala> val age = 19
age: Int = 19
val
字段不能再IDE中重新定义,但是可以在REPL命令行中重新定义。
在Scala中创建新变量时,可以显式声明其类型,如下所示:
val count: Int = 1
val name: String = "Alvin"
但是,通常可以将类型保留为关闭状态,Scala可以为您推断出该类型:
val count = 1
val name = "Alvin"
在大多数情况下,当您关闭类型时,代码更易于阅读,因此首选后者。
例如,在此示例中,数据类型显然是Person
,因此无需在表达式的左侧声明该类型:
val p = new Person("Candy")
相比之下,将类型放在变量名称旁边时,代码会感到不必要的冗长:
val p : Person = new Person("Candy")
总之:
val p = new Person("Candy") // preferred
val p: Person = new Person("Candy") // unnecessarily verbose
您想要显示数据类型的地方之一就是您想要清楚自己所创建的内容。
也就是说,如果您未明确声明数据类型,则编译器可能会对要创建的内容做出错误的假设。
Scala带有您期望的标准数字数据类型。在Scala中,所有这些数据类型都是成熟的对象(不是原始数据类型)。
这些示例说明如何声明基本数据类型的变量:
val b: Byte = 1
val x: Int = 1
val l: Long = 1
val s: Short = 1
val d: Double = 2.0
val f: Float = 3.0
在第四个例子,如果你没有明确指定类型,数量1
将默认为Int
,所以如果你想在其他数据类型中的一种- Byte
,Long
或者Short
你需要显式声明的类型
如图所示,带小数的数字(如2.0)将默认为 Double
,因此,如果需要 Float
,则需要声明 Float
,如上例所示。
因为Int
和Double
是默认数字类型,所以通常在不显式声明数据类型的情况下创建它们:
val i = 123 // defaults to Int
val x = 1.0 // defaults to Double
REPL显示这些示例默认为Int
和Double
:
scala> val i = 123
i: Int = 123
scala> val x = 1.0
x: Double = 1.0
这些数据类型及其范围是:
数据类型 | 可能的值 |
---|---|
Boolean | true 或者 false |
byte | 8位带符号的二进制补码整数(-2 ^ 7至2 ^ 7-1,包括两端) -128至127 |
short | 16位带符号二进制补码整数(-2 ^ 15至2 ^ 15-1,含) -32,768至32,767 |
int | 32位二进制补码整数(-2 ^ 31至2 ^ 31-1,包括两端) -2,147,483,648至2,147,483,647 |
long | 64位二进制补码整数(-2 ^ 63至2 ^ 63-1,包括) (-2 ^ 63至2 ^ 63-1,包括) |
float | 32位IEEE 754单精度浮点数 1.40129846432481707e-45至3.40282346638528860e + 38 |
double | 64位IEEE 754双精度浮点数 4.94065645841246544e-324d至1.79769313486231570e + 308d |
Char | 16位无符号Unicode字符(0到2 ^ 16-1,包括 0)到65,535 |
String | 字符串 |
对于大数,Scala,还包括以下类型BigInt
和BigDecimal
:
var b = BigInt(1234567890)
var b = BigDecimal(123456.789)
BigInt和
BigDecimal
为他们支持你们四则所有运算类型:
scala> var b = BigInt(1234567890)
b: scala.math.BigInt = 1234567890
scala> b + b
res0: scala.math.BigInt = 2469135780
scala> b * b
res1: scala.math.BigInt = 1524157875019052100
scala> b += 1
scala> println(b)
1234567891
Scala还具有String
和Char
数据类型,通常可以使用隐式形式进行声明:
val name = "Bill"
val c = 'a'
再次,您可以使用显式形式,如果您愿意的话:
val name: String = "Bill"
val c: Char = 'a'
如图所示,将字符串括在双引号中,将字符括在单引号中。