一、前言
前面已经学习了Scala中的String,接着学习Scala的Numbers。
二、Numbers
在Scala中,所有的数字类型,如Byte,Char,Double,Float,Int,Long,Short都是对象,这七种数字类型继承AnyVal特质,这七种数字类型与其在Java中有相同的范围,而Unit和Boolean则被认为是非数字值类型,Boolean有false和true两个值,你可以获取到各个数字类型的最值。
复杂的数字和日期
如果需要更强大的数类,可以使用spire,scalalab。
如果需要更强大的日期类,可以使用Joda Time,nscala-time。
2.1 从字符串中解析数字
1. 问题
你想要将字符串类型转化为数字类型。
2. 解决方案
使用String的to*方法即可将String转化为相应的数字。
当无法进行转化时,to*方法可能会抛出NumberFormatException异常。
可以直接使用字符串来创建BigInt和BigDecimal实例(也可能会抛出异常)
处理基和基数
如果在计算时不以10为基(十进制)进行计算,而要使用其他进制,此时Int类的toInt方法不允许传入基和基数,此时需要使用parseInt方法,parseInt可将字符串转化为在指定进制下的值
也可以使用隐式转化来完成上述的功能
3. 讨论
由于在Scala中没有受检查异常,因此你不需要在方法中声明throws NumberFormatException。但是为了使调用者明白该方法可能会抛出异常,你可以使用throws注解
@throws(classOf[NumberFormatException]) def toInt(s: String) = s.toInt
更通常而言,在Scala中使用Option/None/Some进行模式匹配来处理
def toInt(s: String):Option[Int] = { try { Some(s.toInt) } catch { case e: NumberFormatException => None } }
此时你就可以使用不同的方法来调用toInt方法
println(toInt("1").getOrElse(0)) // 1 println(toInt("a").getOrElse(0)) // 0
另外一种使用方法就是使用匹配表达式
toInt(aString) match { case Some(n) => println(n) case None => println("Boom! That wasn't a number.") }
也可以使用如下直接提取出值
val result = toInt(aString) match { case Some(x) => x case None => 0 }
2.2 数字类型间的转化
1. 问题描述
你想要从一种数字类型转化为另一种数字类型,如从Int到Double。
2. 解决方案
不同于Java使用cast方法,Scala中可以直接使用数字类型提供的to*方法。
3. 讨论
在Java中,需要强制转化来将double类型转化为int类型
int a = (int) 100.00;
但是在Scala中,使用to*方法即可完成上述转化,如果你想要避免转化错误,你可以使用isValid方法来测试是否可以转化
2.3 重写默认类型
1. 问题描述
当你给变量赋值时,Scala会自动给变量赋予相应的类型,当你创建数字字段时,你需要重写默认的类型。
2. 解决方案
如果你将1赋值给变量a,那么a默认为Int类型
下面例子重写了默认类型
另一种方法是用类型注释变量
也可以在等号左边进行定义
你也可以在数字前面添加0x或0X来创建十六进制整形
3. 讨论
当创建对象实例时,应该注意如下语法结构
var [name]:[Type] = [initial value]
在初始化数字类型的var字段时,可以使用占位符,其值默认为0,占位符仅仅只在类定义时有效,其他时候则不行,如在方法内部定义不起作用
class Foo { var a: Short = 0 // 定义初始值 var b: Short = _ // 默认为0 }
但在方法中,可以使用如下方法
var name = null.asInstanceOf[String]
当然更好的办法是使用Option/None/Some模式匹配,这样可以避免空值