Scala простая функция возвращает ошибку несоответствия типа - PullRequest
0 голосов
/ 27 мая 2020

У меня есть список векторов. Каждый вектор представляет собой диапазон в виде Vector(Double,Double). Я хотел создать функцию, которая по входному номеру находит, в каком векторе он содержится, и возвращает индекс этого вектора. Я не знаю, есть ли более простой способ сделать это, и я новичок в Scala, но мой код выглядит следующим образом:

val vectors = #List of vectors ( List[scala.collection.immutable.IndexedSeq[Double]] )

def in_range(start: Double, end: Double, x : Double): Boolean = {(x>= start && x<end)}

def find_index(x:Double): Int = {
    for(i <- 0 to n){
     if( in_range(vectors(i)(0),vectors(i)(1),x)){ 
        return i
     }
}

И я получаю следующую ошибку:

<console>:28: error: type mismatch;
 found   : Unit
 required: Int
        for(i <- 0 to 10){
              ^

Ответы [ 2 ]

5 голосов
/ 27 мая 2020

Если for завершается без возврата значения, он вернет Unit, а не требуемый Int, отсюда и сообщение об ошибке.

Но вы должны посмотреть на такие методы, как find для этого что-то вроде того, а не перебирать индексы коллекции. например,

def find_index(x: Double): Int =
  vectors.indexWhere(v => in_range(v(0), v(1), x))
2 голосов
/ 27 мая 2020

В вашем коде много ошибок, давайте исправим их все по очереди.

Самая важная из них - в Scala нет return (ну, он существует, но вы не должны его использовать ) .
В Scala, возврат блока - это возврат его последнего выражения. Таким образом, в вашем случае возврат find_index - это возврат for(){...}, что на самом деле не для l oop, а для понимания ; и если бы вы читали документацию , вы бы знали, что он обессахаривает простой вызов foreach, который возвращает Unit, а не Int.

Итак, вы можете обмануть компилятор с помощью этого:

def find_index(x:Double): Int = {
    for(i <- 0 to n){
     if( in_range(vectors(i)(0),vectors(i)(1),x)){ 
        return i
     }
     -1 // default return value.
}

Но это просто плохой код в Scala. Возможно, вы привыкли к старым императивным циклам (для того, как вы называете вещи, я предполагаю, что у вас есть Python фон) , но Scala не является другим OOP языком , это смесь FP и OOP.
И даже если Scala позволяет вам быть императивным, вы обнаружите, что этот язык предоставляет вам множество полезных инструментов для создания код проще.

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

Еще одна идиоматика c версия кода будет.

def inRange(start: Double, end: Double, x: Double): Boolean =
  x >= start && x < end

def findIndex(vectors: List[(Double, Double)])(x: Double): Option[Int] =
  vectors.iterator.zipWithIndex.collectFirst {
    case ((start, end), idx) if (inRange(start, end, x)) => idx
  }

Примечание: обычно мы не так часто используем индексы. Может быть, вам действительно нужен кортеж вместо индекса кортежа?

Что вы можете использовать, например:

findIndex(List((0, 3), (3, 5), (8, 10)))(3)
// res: Option[Int] = Some(1)
// A index was found.

findIndex(List((0, 3), (3, 5), (8, 10)))(6)
// res: Option[Int] = None
// A index was not found.

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

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