具有相同名称的两个类型参数 [英] two type parameters with the same name
问题描述
我想知道为什么下面的示例允许使用两个具有相同名称("A")的类型参数(名为"A").我知道这是类型参数的命名错误,请不要这样做.
I am wondering why the two type parameters (named "A") with the same name ("A") is allowed as per the example below. I know this is a POOR naming of type parameters, don't do this.
(我的猜测是它们处于不同的作用域级别,例如类级别和函数级别,并且编译器正在使用某种名称处理)
(My guess is that they are on a on a different scope level, e.g. class level and function level, and the compiler is using some kind of name mangling)
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
}
}
2.8.0的示例输出
Example output from 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
推荐答案
Scala中的嵌套作用域可以自由隐藏彼此的符号表.类型不是唯一可以做到这一点的事情.例如:
Nested scopes in Scala are free to shadow each others' symbol tables. Types are not the only things you can do this with. For example:
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."
}
}
}
}
原理是作用域可以控制其名称空间.这很危险,如果您愚蠢地使用它(例如,我分别对三个不同的事物分别使用X
和a
,对两个事物分别使用A
-实际上,您可以替换 every 带有X
的标识符,但Some
中的标识符必须为小写).但这在编写功能代码时也有好处-您不必担心只是因为您碰巧将其放在不同的上下文中而需要重命名一些迭代变量或类型之类的东西.
The principle is that a scope has control over its namespace. This has dangers, if you use it foolishly (e.g. I have used X
and a
for each of three different things, and A
for two--in fact, you could replace every identifier with X
except for the one in the Some
which has to be lower case). But it also has benefits when writing functional code--you don't have to worry about having to rename some iterating variable or type or whatever just because you happen to place it in a different context.
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
}
因此请注意,您有权迷惑自己,并明智地选择不混淆地使用该能力.
So be aware that you have the power to confuse yourself, and wisely choose to use that power non-confusingly.
这篇关于具有相同名称的两个类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!