2017-02-01 6 views
1

Я пишу функцию и имею странную проблему. Я использую сопоставление с образцом, а затем внутренняя функция, которая использует слегка измененную, но практически идентичную картину и не компиляции:Вложенная функция возвращает тип возврата своего родителя

def isTriangular(n: Int): Boolean = { 
    n match { 
    case n if n < 1 => false 
    case _ => triangularMaths(n, 1) 
    } 

    def triangularMaths(j:Int, counter: Int): Boolean = (j, counter) match { 
    case _ if j-counter == 0 => true 
    case _ if j-counter < 0 => false 
    case _ => triangularMaths(j-counter, counter+1) 
    } 
} 

Исправление для этого я просто сделать их два отдельных методами, и они работать до тех пор, пока triangularMaths не вложен. Однако, поскольку triangularMaths относится только к triangular, я бы хотел, чтобы он был вложен. Однако, когда я это делаю, мой компилятор жалуется, говоря мне, что я возвращаю Unit, а не ожидаемый Boolean. Это не имеет никакого смысла, поскольку, как только исходные скобки случая разрешены, возвращая true или false, он должен перейти к концу метода и завершить, исправить? В чем проблема?

+0

Подсказка: возвращаемое значение метода - это значение последнего выражения, оцененного в методе. Подсказка №2: каково последнее выражение, вычисленное в методе? Подсказка №3: ​​каково значение определения функции? –

ответ

3

Это происходит потому, что ваш метод является последним объявлением в области видимости, что делает компилятор испускать значение Unit как возвращаемый тип. Декомпилированный код выглядит следующим образом:

def main(args: Array[String]): Unit = { 
    def isTriangular(n: Int): Boolean = { 
    n match { 
     case (n @ _) if n.<(1) => false 
     case _ => triangularMaths(n, 1) 
    }; 
    def triangularMaths(j: Int, counter: Int): Boolean = scala.Tuple2.apply[Int, Int](j, counter) match { 
     case _ if j.-(counter).==(0) => true 
     case _ if j.-(counter).<(0) => false 
     case _ => triangularMaths(j.-(counter), counter.+(1)) 
    }; 
    () 
    }; 

Сначала определите triangularMaths, а затем вызвать его:

def isTriangular(n: Int): Boolean = { 
    def triangularMaths(j: Int, counter: Int): Boolean = (j, counter) match { 
    case _ if j - counter == 0 => true 
    case _ if j - counter < 0 => false 
    case _ => triangularMaths(j - counter, counter + 1) 
    } 

    n match { 
    case n if n < 1 => false 
    case _ => triangularMaths(n, 1) 
    } 
} 

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

+0

Ага, спасибо. Я попытался установить var 'b: boolean = false' как первую строку' isTriangular', а затем установить вторую строку 'n match':' case _ => b == triangularMaths (n, 1) ' а затем верните 'b' прямо перед закрывающей скобкой всего этого, но он не запомнит изменения на' b', если он получил оценку true. – NateH06

 Смежные вопросы

  • Нет связанных вопросов^_^