2014-12-30 1 views
3

В следующем фрагменте кода, в котором внешние совпадения vars (x, y) соответствуют случаю (xx, yy):Анализатор кода Scala задает имена переменных переменных, которые идентичны внешним сопоставленным переменным - «подозрительное затенение»

scala> val (x,y) = (1,2) 
x: Int = 1 
y: Int = 2 

scala> (x,y) match { 
    | case (xx:Int, yy:Int) => println(s"x=$x xx=$xx") 
    | } 
x=1 xx=1 

Мы могли бы также написано, что код следующим образом:

scala> (x,y) match { 
    | case (x:Int, y:Int) => println(s"x=$x y=$y") 
    | } 
x=1 y=2 

В этом последнем случае Scala анализаторы кода сообщит нам:

Подозрительное затенение переменным рисунком

ОК. Но есть ли ситуация, когда мы могли бы на самом деле неправильно использовать внутреннюю переменную (x или y) вместо исходных внешних переменных соответствия?

Кажется, это чисто стилистическое? Нет реальной возможности для ошибок? Если так, мне было бы интересно узнать, что может быть ошибкой.

+0

Переменная затенение - скрытая ошибка. Lurker - это то, что возникает и укусывает вас, когда вы забыли свой код, когда вернетесь к нему, или b) попросите кого-то нового в этом районе войти и попытайтесь его изучить/сохранить. Как правило, не стоит беспокоиться о том, чтобы оставить затенение на месте. –

+0

@BobDalgleish Я просил явных демонстраций того, как эта «скрывающая ошибка» может проявиться, а не теоретическая. – javadba

+0

Это не наименее теоретически. Я был немного доволен, но в несколько большей функции. Я не мог понять, почему переменная, которую я использовал, не показывала ожидаемое значение. Провел почти час, ударяя головой в отладчик, пока не заметил тень. Сделайте все одолжение и напишите чистый код, пожалуйста! –

ответ

2

Это может привести к путанице:

val x = Some(1) 
val y = Some(2) 

(x, y) match { 
    case (Some(x), Some(y)) => println(s"x=$x y=$y") 
} 

x и y имеют различные типы в зависимости от того, являетесь ли вы внутри или снаружи match. Если бы этот код не использовался просто Option, и он был несколько длиннее, это было бы довольно сложно рассуждать.

Не могли бы возникнуть ошибки? Ничто из того, что я могу думать об этом, не ужасно надуманно. Вы могли бы, например, ошибиться один за другим.

val list = List(1,2,3) 
list match { 
    case x :: y :: list => list // List(3) and not List(1,2,3) 
    case x :: list => list  // List with 1 element, should the outer list have size 2 
    case _ => list    // Returns the outer list when empty 
} 

Не говоря уже о том, какой ужасный беспорядок. В пределах matchlist иногда относится к внутреннему символу, а иногда и к внешнему list.

0

Это просто код, который излишне сложно читать и понимать, нет особых ошибок, которые могут произойти.