Scala 常用整理

Posted 文大侠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala 常用整理相关的知识,希望对你有一定的参考价值。

数据类型

Byte 8位有符号值。范围从-128到127

Short16位有符号值。范围从-32768至32767

Int32 位有符号值。范围从 -2147483648 to 2147483647

Long64位有符号值。 从-9223372036854775808到9223372036854775807

Float32位IEEE754单精度浮点数

Double64位IEEE754双精度浮点数

Char16位无符号Unicode字符。范围由U+0000至U+FFFF

String字符序列

Boolean true或false

Unit对应于没有值

Null空或空引用

Nothing每一个其他类型的子类型; 包括无值

Any Any类型的超类型;任何对象是任何类型

AnyRef任何引用类型的超类型

Byte、Short、Int、Long、Float、Double、Chart、Boolean是值类型。与Java不同的是Scala并不区分原始类型和封装类型,一律是首字母大写。

重点

String是直接引用的java.long.String,Unit 类似java 中的void。

Null是所有AnyRef的子类,Nothing是所有类型的子类,也是Null的子类。

Any是abstract类,它是Scala所有类型的父类。Any 类型的直接后裔是 AnyVal AnyRef 类型。 所有运行环境中的Scala类都是直接或间接继承自Any这个类,类似就是Java中的Object。

AnyRef是所有引用类型的父类。除了值类型,所有类型都继承自AnyRef。

类访问控制

Scala 的访问修饰符(access modifier)和 Java 有如下不同点:

  • 如果不指定任何访问修饰符,那么 Java 会默认为包内部可见,而 Scala 则默认为公开。
  • Java protected 是宽泛的,其作用域包括在任意包中的派生类和当前包中的任意类,而 Scala protected C++C#的类似,只有派生类能够访问。
  • Java 的封装是类级别的。可以在一个类的实例方法中访问该类的任何实例的所有私有字段和方法,在 Scala 中也一样,不过,在 Scala 中也可以进行定制,让其只能在当 前的实例方法中访问,这样就和C++比较像。

可以为 private protected 修饰符指定额外的参数。故而,除了简单地将一个成员标记为 private,还可以标记为 private[AccessQualifier],其中 AccessQualifier 可以是任何封闭类名、一个封闭的包名或者是 this(即实例级别的可见性)。

  • 访问修饰符上的限定词告诉 Scala,对于所有类该成员都是私有的,除了以下情况。 如果没有指定 AccessQualifier(在默认情况下),那么该成员只能在当前类或者 其伴生对象中访问
  • 如果 AccessQualifier 是一个类名,那么该成员可以在当前类、伴生对象以及 AccessQualifier 对应的封闭类和其伴生对象中可访问。
  • 如果 AccessQualifier 是一个封闭的包名,那么该成员可以在当前类、伴生对象 以及所提到的包下面的所有类中访问。
  • 如果 AccessQualifier this,那么将会限制该成员只能在该实例中访问,对 于同一个类的其他实例,也是不可见的,这是所有选项中限制最严格的。

泛型的型变

上界

T <: Pet 表明由 T 表示的类 派生自 Pet 类。这个语法用于定义一个上界。把子类给定义的父类型。

      // 上界
      def copy[T <: Any](x: List[T]): Unit = 
        x.foreach(println(_))
      

      val list1 = List[Any]("23", "34", "45")
      copy(list1)
      val list2 = List[String]("23", "34", "45")
      copy(list2)

下界

D >: S定义D的下界,它可以是类型 S,也可以是它的超类型。 把父类给定义的子类型。
      // 下界
       class Animal()println("Animal")
       class Dog() extends Animalprintln("Dog")
       class Cat() extends Animalprintln("Cat")

      def dump[T>:Dog](x : T): Unit = x

      dump(new Animal())

视界

视界 view bound 必须能转成对应你接口的类,<%比<:适用的范围更广,除了所有的子类型,还允许隐式转换过去的类型。
    import scala.language.implicitConversions
    class Bird 
      def sing = 
    
    class Toy 

    class Consumer() 
      def use[T <% Bird](t: T) = t.sing
    

    class Test extends App 
      implicit def toy2Bird(t: Toy) = new Bird
      val c = new Consumer()
      c.use(new Toy)
    

协变

协变逆变是上下界概念的加强版,上下界是表达两个有继承关系的类之间的关系,而协变逆变是表达两个有继承关系的类的子类之间的关系。

在期望接收一个基类实例的集合的地方,能够使用一个子类实例的集合的能力叫作协变(covariance)。+T 告诉 Scala 允许协变,换句话说,在类型检查期间,它要求 Scala 接受一个

类型或者该类型的派生类型。
      // 协变
      class Generic[+T](o:T)
        val c:T=o
      
      val g1 = new Generic[AnyRef]("String")

逆变

期望接收一个子类实例的集合的地方,能够使用一个超类实例的集合的能

力叫作逆变(contravariance)。

通过使用参数化类型-T 而不是 T,我们可以要求 Scala 为自己的类型提供逆变支持。

      // 逆变
      class Parent() 
      class Children() extends Parent
      class Generic2[-T](o: T) 
        def g(t: T) = 
      
      val c = new Parent()
      val g = new Generic2[Parent](c)
      val g2: Generic2[Children] = g

隐式转换

Scala 将在当前作用域以及我们导入的作用域范围内应用隐式转换。

隐式变量/参数

函数调用可以传递默认参数,但是只能默认定义好,可以通过隐式参数传递默认参数,默认在当前作用域寻找定义的隐式参,参考如下

      def calc(num1:Int)(implicit num2:Int): Int = 
        num1 + num2
      

      def callCalc(): Unit = 
        implicit var num2:Int = 3
        println(calc(1))
        println(calc(1)(3))
      

隐式函数

定义 

import scala.language.implicitConversions
import java.time.LocalDate

// 隐式函数 扩展Int能力
// 利用Scala 对于点号和圆括号的可选性处理,实现DSL

class DateHelper(offset: Int) 
  def days (when: String): LocalDate = 
    val today = LocalDate.now
    when match 
    case "ago" => today.minusDays (offset)
    case "from_now" => today.plusDays (offset)
    case _ => today
    
  


object DateHelper 
  val ago = "ago"
  val from_now = "from_now"

  implicit def convertInt2DateHelper(offset: Int): DateHelper = new DateHelper(offset)

调用

      import DateHelper._

      val past = 2 days ago
      val appointment = 5 days from_now
      println(past)
      println(appointment)

隐式类

可以将一个类标记为 implicit 类。当使用隐式类的时候,Scala 设置了一些限制。其中最值得注意的是,它不能是一个独立的类,它必须要 在一个单例对象、类或者特质中。
//定义
object DateUtil 
  val ago = "ago"
  val from_now = "from_now"

  implicit class DateHelper(val offset: Int) 

    import java.time.LocalDate

    def days(when: String): LocalDate = 
      val today = LocalDate.now
      when match 
        case "ago" => today.minusDays(offset)
        case "from_now" => today.plusDays(offset)
        case _ => today
      
    
  


// 调用
      import DateUtil._

      val past = 2 days ago
      val appointment = 5 days from_now
      println(past)
      println(appointment)


 

以上是关于Scala 常用整理的主要内容,如果未能解决你的问题,请参考以下文章

Scala的协变covariant(+),逆变contravariant(-),上界(<:),下界(;:)

Scala的协变covariant(+),逆变contravariant(-),上界(<:),下界(;:)

19.scala的类型上下界

类型参数,协变逆变,上界下界

Scala的泛型

了解上界和下界?在 Java 泛型中