Понимание вызова по имени в Scala

Я новичок в языке scala, поэтому буду признателен, если кто-нибудь объяснит мне этот фрагмент кода:

object C  {

  def main(args: Array[String]) = {
    measure("Scala"){
      println("Hello Back")
    }
  }

  def measure(x: String)(y: => Unit){
   println("Hello World " + x)
  }
}

Вывод консоли:

Hello World Scala

Мой вопрос: почему программа не напечатала Hello Back? Также есть функция/объект, телом которой является инструкция println("Hello Back"); хранится где-то в куче?


person sasuke    schedule 22.11.2016    source источник
comment
Если вы хотите понять базовую языковую функцию, велика вероятность, что кто-то уже спрашивал об этом.   -  person Jasper-M    schedule 22.11.2016


Ответы (2)


{
      println("Hello Back")
}

это блок кода, равный:

def f = {println("Hello World")}
measure("Scala")(f)

поэтому для метода measure вам нужно явно вызвать:

  def measure(x: String)(y: => Unit){
   println("Hello World " + x)
   y
  }
person chengpohi    schedule 22.11.2016
comment
Спасибо за подробное объяснение - person sasuke; 22.11.2016
comment
{} — это не метод, это альтернатива написанию () в данном случае: scala> :k {println("a")} scala.Unit's kind is A, а также: scala> def foo(i: Int) = i => scala> foo{1} res2: Int = 1. Есть несколько применений {} в Scala;). Возможно, лучше было бы сказать: это кодовый блок. - person yǝsʞǝla; 22.11.2016
comment
Вызов {...} блока кода и введение def по-прежнему означает, что существует разница между measure("Scala") { println("Hello Back") } и measure("Scala")( println("Hello Back" ). Нет. Что такое println("Hello Back"), так это аргумент по имени. И причина не в фигурных скобках, а в том, что y объявлено именно так. Если вы удалите => из y, вы все равно можете написать measure("Scala") { println "Hello Back"} (или measure("Scala")(f), если хотите), и println будет выполнено немедленно. - person sepp2k; 22.11.2016

Что отличает параметры по имени от обычных, так это то, что выражение аргумента оценивается всякий раз, когда параметр используется. Поэтому, если вы используете его дважды, выражение оценивается дважды. И если вы его вообще не используете, он никогда не оценивается.

Итак, в вашем случае «Hello Back» не печатается, потому что вы никогда не используете y.

Также есть функция/объект, телом которой является инструкция println("Hello Back"); хранится где-то в куче?

Сгенерированный код для параметров по имени такой же, как и для функций, поэтому он создаст объект функции в куче.

person sepp2k    schedule 22.11.2016
comment
Привет @sepp2K, у меня есть небольшой вопрос. Что такое тип данных y, когда я определяю y как (y: => Unit). Это не функция, и я не думаю, что это метод. - person Frankie; 22.11.2016