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
的输出类型取决于传递的参数,但不需要添加通用参数。
定义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
的输出类型取决于传递的参数,但不需要添加通用参数。