Почему Scala путается в типе возвращаемых данных?

#scala

Вопрос:

У меня есть следующий код Scala:

 def isOpen(c: Char, openC: List[Char]) = {
  if(c == '(') openC :  '(';
  else if(c == ')') openC.reverse.tail.reverse;
}
 

Это попытка добавить элемент в openC список, если условия выполнены, а в случае, если это не так, он пытается включить все элементы в список, за openC исключением последнего добавленного. Проблема, которую я не могу понять, как решить, заключается в том, что Scala интерпретирует эту функцию для возврата Any типа, когда я хотел бы, чтобы это было List[Char] . Я тоже попытался переписать это с ListBuffer[Char] помощью шрифта. Я пытаюсь выполнить его в функциональной манере программирования, не полагаясь на val объявления.

Ранее на этом форуме был дан ответ на аналогичный вопрос, в котором говорилось, что это связано с тем, что Scala «путается» при использовании оператора if-else, который выполняет дальнейшие действия после их выполнения. Но я не уверен, как это применимо здесь. Я все еще пытаюсь понять, как это работает.

Комментарии:

1. эта else деталь отсутствует

2. Кстати, рекомендуется использовать явные типы возвращаемых данных. Специально для общедоступных методов это помогает компилятору, он выдает лучшие сообщения об ошибках и помогает вам быстрее обнаруживать ошибки.

3. openC.reverse.tail.reverse === openc.init Кроме того, лучше иметь дело с List s в обратном порядке: тогда вы могли бы сделать '(' :: openC и openC.tail для ваших двух случаев, которые оба являются постоянным временем, а не линейным, как у вас сейчас. И тогда, reverse в конце концов, вы получите только окончательный результат, когда закончите с этим.

Ответ №1:

Ваше if выражение имеет тип Any , потому что

  • если c ( , то это a List[Char]
  • если c ) , то это a List[Char]
  • в противном случае ни одна ветвь if не применяется, так что это Unit

Наименьшая верхняя граница Unit и List[Char] есть Any , таким образом, это тип результата if .

Если вы хотите , чтобы тип результата был List[Char] таким, вам придется добавить else предложение, чтобы перехватывать случаи, которые не были обработаны ранее if / else if s, что приводит к a List[Char] .

Ответ №2:

вы упускаете еще одно утверждение. В случае, если вы не дадите оператор else, он примет любой тип возвращаемого значения

 def isOpen(c: Char, openC: List[Char]) = {
  if(c == '(') openC :  '('
  else if(c == ')') openC.reverse.tail.reverse
  else openC.reverse.tail.reverse
}