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 Animal{println("Dog")}
       class Cat() extends Animal{println("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)


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值