Scala中`Something#A`指代什么?代码里`#`符号含义技术咨询
Scala中
Something#A的含义详解 嘿,这个#符号在Scala里叫做类型投影(Type Projection),专门用来处理内部类型或者路径依赖类型的场景,我给你一步步拆解清楚:
核心概念
当你定义了一个包含内部类型的类/特质时,比如:
class Something { type A = String // 内部类型A }
这里的Something#A表示的是所有Something及其子类实例中内部类型A的公共抽象类型——简单说,它是从Something这个“外部”类型里提取出来的内部类型引用,不需要绑定到某个具体的Something实例上。
和.访问内部类型的区别
你可能会好奇,那和something.A(某个具体实例的内部类型)有啥不一样?
something.A是路径依赖类型:它绑定到具体的something实例,不同实例的A可能是完全不同的类型(比如如果Something是特质,子类可以重写type A)。Something#A是类型投影:它是对所有Something家族实例的A类型的统一抽象,代表这些路径依赖类型的公共超类型。
结合你的代码例子分析
看你给出的代码:
case class WithRole(role: Role) extends Authorization[User, DefaultEnv#A]
这里的DefaultEnv应该是一个定义了内部类型A的特质/类,比如类似这样:
trait DefaultEnv { type A = RequestContext // 假设是某个上下文类型 }
使用DefaultEnv#A的原因在于:Authorization是一个泛型特质/类,它的第二个类型参数需要一个具体的类型。而我们不需要依赖DefaultEnv的某个实例(毕竟DefaultEnv可能是一个抽象特质,或者我们不想绑定到特定实例),直接通过类型投影DefaultEnv#A就能引用它内部定义的A类型,完美满足泛型参数的要求。
再举个简单例子加深理解
trait Box { type Content def open: Content } // 用类型投影定义方法返回值类型 def takeContent(box: Box): Box#Content = box.open
这里Box#Content就表示任意Box实例的内容类型,不管这个Box是装苹果的还是装书的,我们都能统一处理它的内容。如果换成box.Content,那就是这个具体box实例的内容类型,在这个例子里效果差不多,但当涉及到泛型继承、抽象类型的复用场景时,类型投影的灵活性就体现出来了。
内容的提问来源于stack exchange,提问作者Manu Chadha
相关产品推荐
相关产品推荐

