两个具有相同名称的类型参数

olu*_*ies 6 generics scala

我想知道为什么允许两个具有相同名称("A")的类型参数("A"),如下例所示.我知道这是类型参数的POOR命名,不要这样做.

(我的猜测是它们处于不同的范围级别,例如类级别和功能级别,并且编译器正在使用某种名称修改)

class  MyTest[A](){
    type MyType  = A

    def checkString[A](value:A, x:MyType):A = { 
       value match {
         case x:String => println("Value is a String")
         case _ => println("Value is not a String")
       }

       x match {
          case x:String => println("x is a String")
          case _ => println("x is not a String")
       }

       value
   }
}
Run Code Online (Sandbox Code Playgroud)

2.8.0的示例输出

scala> val test = new MyTest[Int]
test: MyTest[Int] = MyTest@308ff65f

scala> test.checkString("String",1)
Value is a String
x is not a String
res7: java.lang.String = String

scala> test.checkString(1,1)
Value is not a String
x is not a String
res8: Int = 1
Run Code Online (Sandbox Code Playgroud)

Rex*_*err 8

Scala中的嵌套作用域可以自由地影响彼此的符号表.类型不是你可以做的唯一事情.例如:

class X[A](a: A) {
  def X[A](a: A) {
    if (a==this.a) {
      val X = Some(this.a)
      X match {
        case Some(a) => "Confused much yet?"
        case _ => "Just because you can do this doesn't mean you should."
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

原则是范围可以控制其命名空间.这也有危险,如果你愚蠢地使用它(例如我用Xa供三个不同的东西,A有两个-事实上,你可以取代每个标识符为X除了一个在Some它必须是小写).但是在编写功能代码时它也有好处 - 您不必担心必须重命名一些迭代变量或类型或其他只是因为您碰巧将它放在不同的上下文中.

def example = {
  val a = Array(1,2,3,4,5)
  val sumsq = a.map(i => i*i).sum
  a.map(i => {
    val a = Array.range(1,i)
    val sumsq = a.map(i => i*i).sum  // Cut and paste from above, and works!
    sumsq + i
  }).sum
}
Run Code Online (Sandbox Code Playgroud)

所以请注意,你有能力混淆自己,并明智地选择使用这种权力而不是混乱.