LINUX.ORG.RU

VerifyError и Scala


0

0

Почему такой код при запуске выбрасывает исключение?

package my

class Test {	
	def this(un: Int) = {
		this()
		def test(acc: Array[Byte]) = {	
			acc.map((f: Byte) => 42)
		}
	}
}

object Test {	
  def main(args: Array[String]): Unit = {
	  val q = new Test(42)
  }
}
java.lang.VerifyError: (class: my/Test, method: test$1 signature: ([B)[I) Incompatible argument to function
Exception in thread "main" 

Если убрать «acc.map((f: Byte) => 42)», или метод(?) test вынести за пределы конструктора, то все ОК. ЧЯДНЕТ?


вижу описание конструктора класса Test(Int), а где конструктор Test()?

ma1uta ★★★ ()

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

Но всё равно такой код, не имеет смысла.

Zenom ★★★ ()

да и что делает метод test в конструкторе?

ma1uta ★★★ ()
Ответ на: комментарий от Zenom

> вижу описание конструктора класса Test(Int), а где конструктор Test()?

А он разве автоматически по умолчанию не создастся?

Scala-2.7.7 должна на это ругаться, что нужно выражение, а не объявление.

Scala-2.8

А почему бы и не объявление? http://programming-scala.labs.oreilly.com/ch02.html#NestingMethodDefinitions

Но всё равно такой код, не имеет смысла.

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

да и что делает метод test в конструкторе?

test используется как параметр для map в конструкторе (код не показан).

SSZB ()
Ответ на: комментарий от SSZB

Scala-2.8

Ну да, иначе бы не скомпилировалось.

А почему бы и не объявление?

Как бы очевидно, что функции могут быть вложенными. Дело в том, что метод/конструктор не может состоять только из объявления.

test используется как параметр для map в конструкторе (код не показан).

Я бы попробовал переписать его как анонимную функцию. Благо, синтаксис позволяет делать это понятно.

some_seq map { seq_elem =>
    //...
    //...
    //...
}
Zenom ★★★ ()
Ответ на: комментарий от Zenom

Ну да, иначе бы не скомпилировалось.

А есть недоверие к 2.8?

Дело в том, что метод/конструктор не может состоять только из объявления.

Да легко:

class Test {
	val q = new ArrayBuffer[Set[Byte]]
	
	def this(un: Int) = {
		this()
		def test(acc: ArrayBuffer[Set[Byte]]) = {	
			acc.map((f: Set[Byte]) => Set[Byte](42))
		}
		q.append(Set[Byte](42))
	}
}

Дает такой же эффект.

Я бы попробовал переписать его как анонимную функцию. Благо, синтаксис позволяет делать это понятно.

Возможно, но почему я не могу сделать так как я сделал?

SSZB ()

очевидно, в теле функции test есть недопустимая операция
явно ошибка в компиляторе, можно посмотреть байт-код, и сказать, где именно

note173 ★★★★★ ()
Ответ на: комментарий от SSZB

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

С анонимной функцией работает, я проверил. Конечно, должно работать и в изначальном варианте. Так что надо попробовать воспроизвести на максимально различном коде, сообщить о баге и использовать анонимную функцию как вполне приемлемый workaround.

Zenom ★★★ ()

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

Rastafarra ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.