Scala基础语法入门(二) 数据类型&类型转换

Scala基础语法入门(二) 数据类型&类型转换,第1张

​🏠​ 个人主页:csdn春和
​🛰​ 推荐专栏:更多专栏尽在主页!
 JavaWeb专栏(从入门到实战超详细!!!)
 SSM专栏 (更新中)
​📖​ 本期文章:Scala基础语法入门(二) 数据类型&类型转换
如果对您有帮助还请三连支持,定会一 一回访!


本文目录
  • 一、Scala数据类型
    • 1.1、回顾java数据类型
    • 1.2、Scala数据类型——概览
    • 1.3、Scala数据类型——值类型(AnyVal)
    • 1.4、Scala数据类型——引用类型(AnyRef)
    • 1.5、Scala数据类型——超类 Any
    • 1.6、Scala数据类型——Nothing
  • 二、类型转换
    • 2.1、自动类型转换
    • 2.2、强制类型转换
    • 2.3、数值类型和String类型转换
    • 2.4、强转溢出面试题

一、Scala数据类型

Scala与java有着相同的数据类型,但是又有不一样的地方

1.1、回顾java数据类型

java中有基本数据类型(八大数据类型):char byte short int long float double boolean

java引用类型(对象类型):Object 数组 字符串 包装类 集合 POJO对象等

Java基本类型的包装类:Character、Byte、Short、Integer、Long、Float、Double、Boolean

由于Java有基本类型,而且基本类型不是真正意义的对象,即使后面产生了基本类型的包装类,但是仍 然存在基本数据类型,所以Java语言并不是真正意义上的面向对象。

Java中基本类型和引用类型没有共同的祖先。

问题思考:类型和泛型的区别?

1.2、Scala数据类型——概览

1、scala中一切皆对象,都是Any的子类

2、Scala中数据类型分为两大类:数值类型(AnyVal)引用类型(AnyRef) 他们都是对象

3、Scala中数据类型任然遵守 低精度的值类型向高精度的值类型自动转换,即隐式转换

4、Scala中的StringOps是对java中的String增强

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

6、Null是一个数据类型,只有一个对象就是null,他是所有引用类型(AnyRef)的子类

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

1.3、Scala数据类型——值类型(AnyVal)
object Scala05_DataType01 {

  def main(args: Array[String]): Unit = {

    // Scala数据类型 任意值类型 AnyVal
    val b: Byte = 1
    val s: Short = 1
    val c: Char = 'c'
    val i: Int = 1
    val l: Long = 900
    val f: Float = 10.4f
    val d: Double = 20.3
    val flag: Boolean = false
    val unit:Unit = say() // Unit 是一个类型 这个类型只有一个对象 () 打印出来就是一个()

    println(unit)

  }

  def say(): Unit ={

  }
}

我们点击源码查看:

正好对应上图

1.4、Scala数据类型——引用类型(AnyRef)

package com.zhou.scala.chapter1

import com.zhou.scala.test.User

/**
 * @author it春和
 * @create 2022-05-05 9:18
 */
object Scala05_DataType02 {

  def main(args: Array[String]): Unit = {

    // TODO 数据类型
    // 引用类型 AnyRef

    val list: AnyRef = List(1, 2, 3, 4) // 所有的scala集合
    val user: AnyRef = new User(1, "张无忌") // 所有的java类
    val obj: AnyRef = Scala05_DataType01 // 其他scala类

    // Null在scala中是一个类型 只有一个对象 就是 null 打印的就是null
    val n: Null = null

    val user1: User = null // 这样也可以 因为在Scala中Null是他们的子类型

    println(list)
    println(user)
    println(obj)
    println(n)
    println(user1)

  }
}
1.5、Scala数据类型——超类 Any

我想给一个变量既赋值一个字符串又能赋值为数值该怎么做?

我们知道当我们省略类型scala会根据值自动推导,显而易见v是String类型的 将String类型的变量修改为数值肯定不行 那么Scala是怎样实现的?

我们将变量定义为Any超类 就可以了

1.6、Scala数据类型——Nothing

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

def test1(): Nothing = {
  throw new Exception()
}
二、类型转换 2.1、自动类型转换

隐式转换 在scala中存在隐式转换

object Scala05_DataType04 {
  def main(args: Array[String]): Unit = {
    // 编译器将类型进行了转换 所以可以编译通过 即隐式转换 这个过程我们是看不见的
    val b:Byte = 20
    val s:Short = b
    val i:Int = s
    val l:Long = i
  }
}

当 Scala 程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数值类型,这

个就是自动类型转换(隐式转换)。数据类型按精度(容量)大小排序为

(1)自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成 精度大的那种数据类型,然后再进行计算。

(2)把精度大的数值类型赋值给精度小的数值类型时,就会报错,反之就会进行自动 类型转换。

(3)(byte,short)和 char 之间不会相互自动转换。 char只会转为int

(4)byte,short,char 他们三者可以计算,在计算时首先转换为 int 类型。

  def main(args: Array[String]): Unit = {
    //(1)自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有 数据转换成精度大的那种数值类型,然后再进行计算。
    var n = 1 + 2.0
    println(n) // n 就是 Double
    
    //(2)把精度大的数值类型赋值给精度小的数值类型时,就会报错,反之就会进行自动类型转换。
    var n2 : Double= 1.0
//    var n3 : Int = n2 //错误,原因不能把高精度的数据直接赋值和低 精度。
    
//    (3)(byte,short)和 char 之间不会相互自动转换。
    var n4 : Byte = 1
//    var c1 : Char = n4 //错误
    var n5:Int = n4
    
    //(4)byte,short,char 他们三者可以计算,在计算时首先转换为 int 类型。
    var n6 : Byte = 1
    var c2 : Char = 1

    val res: Int = n6 + c2
    println(res)
    
  }

Scala 还提供了非常强大的隐式转换机制(隐式函数,隐式类等),这里先不深究

2.2、强制类型转换

自动类型转换的逆过程,将精度大的数值类型转换为类型小的数值类型,使用时要加上强制转换函数,强转会造成精度降低或溢出

// java中的强制转换
int num = (int) 9.0;
// scala中的强制转换
var num:Int = 9.0.toInt

(1)将数据由高精度转换为低精度,就需要使用到强制转换

(2)强转符号只针对于最近的 *** 作数有效,往往会使用小括号提升优先级

def main(args: Array[String]): Unit = {
  // TODO 强制类型转换

  //(1)将数据由高精度转换为低精度,就需要使用到强制转换
  var n1: Int = 2.5.toInt // 这个存在精度损失
  println(n1)

  //(2)强转符号只针对于最近的 *** 作数有效,往往会使用小括号提升优先级
  var r1: Int = 10 * 3.5.toInt + 6 * 1.5.toInt // 10 *3 + 6*1 = 36
  var r2: Int = (10 * 3.5 + 6 * 1.5).toInt // 44.0.toInt = 44
  println(r1)
  println(r2)

}

2.3、数值类型和String类型转换

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

(1)基本类型转 String 类型(语法:将基本类型的值+“” 即可)

(2)String 类型转基本数值类型(语法:s.toInt s.toDouble)

def main(args: Array[String]): Unit = {
  // TODO 数值类型和String类型的相互转换

  // 1、基本类型 ---> String 类型(语法:将基本类型的值+"" 或者 toString 即可)
  var str1: String = true + ""
  var str2: String = 4.5 + ""
  var str3: String = 100 + ""
  var str4: String = 100.toString
    
  // 2、String类型 ---> 基本数值类型(语法:调用相关 API)
  var s: String = "12"
  var n1: Byte = s.toByte
  var n2: Short = s.toShort
  var n3: Int = s.toInt
  var n4: Long = s.toLong

}

 在将 String 类型转成基本数值类型时,要确保 String 类型能够转成有效的数据,比如我 们可以把"123",转成一个整数,但是不能把"hello"转成一个整数。 var n5:Int = “12.6”.toInt 会出现 NumberFormatException 异常。

2.4、强转溢出面试题
  def main(args: Array[String]): Unit = {
    // TODO 强转溢出面试题

//    var n:Int = 128
    var n:Int = 130

    var b:Byte = n.toByte

    println(b)

  }

我们知道byte的范围是-128~127

我们将130超处理这个范围的值强转为byte能否成功 会不会报错呢?

我们发现运行结果直接变为负数,这是怎么回事。

按照字节保存数据在底层主要是以补码的形式保存 而强制转换简单粗暴的进行截断

比如int有四个字节 而byte只有一个字节 所以强转截取最后一个字节

分析

/*
* 128 int类型 占4字节 32 位
* 原码:0000 0000 0000 0000 0000 0000 1000 0000
* 补码:0000 0000 0000 0000 0000 0000 1000 0000
* 截取1个字节做强转:Byte
* 得到的补码:1000 0000
* 符号位为1 表示是负数 且是最小的负数-127
* */

/*
* 130 int类型 占4字节 32 位
* 原码:0000 0000 0000 0000 0000 0000 1000 0010
* 补码:0000 0000 0000 0000 0000 0000 1000 0010
* 截取1个字节做强转:Byte 负数的补码:符号位不变 其余位取反+1
* 得到的补码:1000 0010  负数的补码 = 反码 + 1
* 对应的反码:1000 0001  补码 - 1 得到反码
* 对应的原码:1111 1110  反码取反得到原码
* 对应的数 : -126
* */

所以一个int型的数值强转为byte型可能会存在精度缺失或溢出的问题 (超过-128~127范围)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/870959.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存