scala类型系统:8) type关键字

scala里的类型,除了在定义class,trait,object时会产生类型,还可以通过type关键字来声明类型。

type相当于声明一个类型别名:

scala> type S = String
defined type alias S

上面把String类型用S代替,通常type用于声明某种复杂类型,或用于定义一个抽象类型。

场景1 用于声明一些复杂类型,比如下面声明一个结构类型

scala> type T = Serializable {
 |          type X
 |          def foo():Unit
 |     }
defined type alias T

这个结构类型内部也允许通过type来定义类型,这里对X没有赋值表示X是一个抽象类型,需要子类型在实现时提供X具体的类型。下面是一个T类型的具体实例:

scala> object A extends Serializable{ type X=String; def foo(){} }

scala> typeOf[A.type] <:< typeOf[T]
res19: Boolean = true

场景2 用于抽象类型

scala> trait A { type T ; def foo(i:T) = print(i) }

scala> class B extends A { type T = Int }

scala> val b = new B

scala> b.foo(200)
200

scala> class C extends A { type T = String }

scala> val c = new C

scala> c.foo("hello")
hello

scala类型系统:8) type关键字》上有7个想法

  1. 呃,感觉应该先abstract type member后type alias,毕竟前者是功能性的,后者只是sugar。

  2. 这里如何解释?

    scala> type S = String
    defined type alias S

    scala> typeOf[String]
    res14: reflect.runtime.universe.Type = String

    scala> typeOf[S]
    res15: reflect.runtime.universe.Type = S

    scala> typeOf[S] == typeOf[String]
    res16: Boolean = false

    • 你这是两个对象的引用比较,要证明这两个类型是否相同用:
      typeOf[S] =:= typeOf[String]

      • 有道理。
        应该用getClass试试。

        typeOf[T] 是一个Type对象。

        不过 typeOf[S] =:= typeOf[String]这个也是不对的哦, 因为 =:= 的意思是 =:=[X, Y] , 产生一个新的类型。
        scala> typeOf[S] =:= typeOf[String]
        :9: error: not found: value typeOf
        typeOf[S] =:= typeOf[String]
        ^
        :9: error: not found: value typeOf
        typeOf[S] =:= typeOf[String]
        ^

        scala> type S = String
        defined type alias S

        scala> val k = new S
        k: String = “”

        scala> val t = new String
        t: String = “”

        scala> k.getClass
        res0: Class[_ t.getClass
        res1: Class[_ <: String] = class java.lang.String

  3. 用 =:=[A, B] 可以证明A,B两个类型是否等价的,B是A的别名的话,它两是等价的。
    但A, B仍是两种类型,它们的type对象是不同的。

    scala> import scala.reflect.runtime.universe.typeOf
    import scala.reflect.runtime.universe.typeOf

    scala> type S = String
    defined type alias S

    scala> typeOf[S] =:= typeOf[String]
    res0: Boolean = true

    • 我来补充一下泛型的情形,根据个人喜好做选择
      trait A[T]{
      // 此时不再有type,取而代之的是泛型参数T
      def foo(I: T):Unit = println(i)
      }

      // 本例中指定T为Int类型
      // 继承时指定T的具体类型
      class B extends A[Int]
      val b = new B
      b.foo(200)
      // 若不指定具体类型,则继承时保留泛型参数T
      class B[T] extends A[T]
      // 在实例化时指定类型为Int
      val b = new B[Int]
      b.foo(200)

      // 本例中指定T为String类型
      // 继承时指定T的具体类型为String
      class C extends A[String]
      val c = new C
      c.foo(“hello”)

      // 在实例化时指定具体类型为String
      class C[T] extends A[T]
      val c = new C[String]
      c.foo(“hello”)
      // 总结:type提供了语法糖,将泛型作为成员变量,将指定具体类型这一操作延迟到继承和实例化阶段完成,如果不使用type,则必需在类型中携带泛型参数T,直到泛型参数T被明确指定为具体类型为止

发表评论

电子邮件地址不会被公开。 必填项已用*标注