Несоответствие типов Scala в операторе if - PullRequest
0 голосов
/ 03 ноября 2019

Хотите знать, почему этот код не работает, я что-то упустил?

def treemin(lst: List[Any]): Int = {
  var MaVar: Int = 1000{
  case (sum,leaf: Int)  =>
    if(leaf < MaVar) {MaVar = leaf}
  }
}

Ошибка, с которой я столкнулся здесь:

if(leaf < MaVar) {MaVar = leaf}

Ошибка:

Ошибка: несоответствие типов;найдено: Требуется юнит: Int

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

Примечание: Это хороший подход для получения минимального листа дерева?

Я получил дерево:

enter image description here

И я пытаюсь создать функцию, которая будет возвращать минимальный лист, например, здесь он вернет 2.

1 Ответ

0 голосов
/ 03 ноября 2019

На самом деле в вашем коде есть две ошибки:

def treemin(lst: List[Any]): Int = {
  var MaVar: Int = 1000{
  case (sum,leaf: Int)  =>
    if(leaf < MaVar) {MaVar = leaf}
  }
}

Первая ошибка:

         var MaVar: Int = 1000{
                              ^
On line 2: error: Int(1000) does not take parameters
       }
       ^

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

def treemin(lst: List[Any]): Int = {
  var MaVar: Int = 1000

  {
    case (sum,leaf: Int)  =>
      if(leaf < MaVar) {MaVar = leaf}
  }
}

Однако теперь вы получаете еще одну ошибку, потому что теперь фигурные скобкиинтерпретируется как создание анонимной функции:

         {
         ^
On line 4: error: missing parameter type for expanded function
       The argument types of an anonymous function must be fully known. (SLS 8.5)
       Expected type was: Int

Есть способы обойти это, но дело в том, что создавать здесь новую лексическую область не имеет смысла, так как вы не определяете никакойпеременные в нем, так что в первую очередь ничего не нужно «охватывать».

Просто избавьтесь от этого:

def treemin(lst: List[Any]): Int = {
  var MaVar: Int = 1000
  case (sum,leaf: Int)  =>
    if(leaf < MaVar) {MaVar = leaf}
}

Теперь мы получаем еще одну ошибку:

         case (sum,leaf: Int)  =>
         ^
On line 3: error: '}' expected but 'case' found.

Что, по сути, говорит нам, что case должно сочетаться с оператором match. Поскольку мне не совсем понятно, с чем вы пытаетесь сопоставить, я не могу исправить код дальше.

Это приводит нас ко второй ошибке, которая на самом деле довольно проста:

       }
       ^
On line 6: error: type mismatch;
        found   : Unit
        required: Int

Это указывает на закрывающую фигурную скобку вашего метода и, по сути, говорит, что вы пообещали в своем определении метода, что метод возвращает Int, но вы на самом деле возвращаете Unit. На самом деле, вы вообще ничего не возвращаете . Если вы ничего явно не возвращаете, то возвращается значение последнего выражения, вычисленного внутри метода.

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

var MaVar: Int = 1000

Это задание. Присвоения оцениваются как Unit, поэтому, если это было последним вычисленным выражением, тогда возвращаемое значение действительно будет (), которое является единичным экземпляром Unit.

Другоекандидатом на последнее выражение, вычисленное внутри метода, является условное выражение:

if(leaf < MaVar) {MaVar = leaf}

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

«Истинная» ветвь в вашем условном выражении снованазначение, и, как мы установили выше, назначение оценивается как () aka Unit.

"ложная" ветвь в вашем условном не существует , но она имеет для оценки что-то , если оно взято, потому что в Scala все является выражением (нет операторов) и, следовательно, все оценивается как значение . Ну, значение, которое представляет отсутствие разумного возвращаемого значения, является (как вы уже догадались) () aka Unit.

Итак, как бы вы ни смотрели на это, ваш метод всегда возвращает Unit, тогда как онна самом деле обещает вернуть Int. Вот почему получается ошибка типа.

У вашего метода есть пара других странностей: он принимает аргумент, но никогда не использует его. И аргумент имеет тип List[Any], который представляет собой огромный красный флаг. В Scala очень мощная система типов, почти никогда не бывает, что вы не знаете, что это за тип. Any - самый бесполезный тип, поскольку он ничего не говорит вам о том, что это за тип и что он может делать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...