当我在Intellij中键入以下代码时,它会突出显示匹配中的x,并警告"由可变模式进行可疑阴影">
val x = "some value"
"test" match {
case x =>
}
它建议我将其更改为:
val x = "some value"
"test" match {
case `x` => //note backticks
}
什么是可疑的阴影,背景是什么?!
case x
创建一个名为x
的变量,该变量将匹配所有内容,并且由于已经存在具有相同名称的变量,因此可以使用相同名称对其进行阴影处理。
case `x`
使用之前声明的变量x
的值,并且只匹配具有相同值的输入。
PS
如果变量的名称如中那样大写,则可以去掉后面的勾号
case Pi
观看图案匹配释放更多。
Scala程序设计节选[1]:
文字标识符是一个包含在反引号
(`...`)
中的任意字符串。文字标识符的一些例子有:`x` `<clinit>` `yield`
其思想是,您可以将运行时接受的任何字符串作为标识符放在反勾号之间。结果总是一个Scala标识符。即使后面的记号中包含的名称是Scala保留字,这也能起作用。一个典型的用例是访问Java的
Thread
类中的静态yield
方法。不能写Thread.yield()
,因为yield
是Scala中的保留字。但是,您仍然可以在backticks中命名该方法,例如Thread.`yield`()
。
简而言之,使用`x`
,您将与x
的值相匹配。使用x
,您将创建一个与任何内容匹配的新变量,并将结果保存到x
。
[1] M.Odersky,L.Spoon,B.Venners,Scala编程,第2版,核桃溪:Artima出版社,2010年,第109页http://www.artima.com/pins1ed/functional-objects.html#i1517246665-1
匹配中的case生成一个新符号x
来接收匹配值。这是因为,按照惯例,小写标识符应指代值,大写标识符应指类型。
因此,case语句生成一个与初始值同名的新符号x
,"遮蔽"原始值。"隐藏"IntelliJ意味着它隐藏任何其他同名值,从而使它们不可访问。
它将其标记为可疑,因为这种阴影通常是无意的,就像您的示例中的情况一样。
关于backticks,请参见例如此处:需要澄清Scala文本标识符(backticks(不过,它们似乎并不是一个好的解决方案。最好选择一个不同的名字。