scala 中类型别名和泛型 class 的区别

difference between type alias and generic class in scala

定义class类型参数有两种方式:

trait A { type T ; def foo(i:T) = print(i) }
class B extends A { type T = Int }

trait A[T] { def foo(i:T) = print(i) }
class B extends A[Int] {}

Scala 编译器有什么区别?它们完全一样吗? 哪种方式更好(在哪些情况下)?

前者不[只是]一个类型别名,它是一个依赖于路径的类型。表示 T 的类型包含在 A.

的实例中

对于路径相关的类型,在给定 A 的实例的情况下不可能知道 T 的类型(仅当您知道子类型时)。考虑

val a: A = ???
a.foo(???)

对于泛型,我们(通常)知道 T 的类型,但不知道 A 的子类型。考虑

val a: A[Int] = ???
a.foo(5)

另一方面,您可以使用路径相关类型

trait A { type T; def foo(s:String): T }
class B extends A { type T = Int; def foo(s: String) = s.length }

def fun(a: A): A#T = a.foo("hello")
val out: Int = fun(new B()) // 5

我们可以让 fun 的输出类型取决于传递的参数,但不需要添加通用参数。