2015-05-11 3 views
1

, если при вызове по значению
по значению & по имени в Scala => взаимно однозначное соответствие

val f: (Int) => Int = {(i) => {i * i}} # f: Int => Int = <function1>
является сокращением для
val f: Function1[Int, Int] = {(i) => {i * i}} # f: Int => Int = <function1>

тогда, когда по телефону по-умолчанию
val f: (=> Int) => Int = {(i) => {i * i}} # f: (=> Int) => Int = <function1>
является сокращением для
? что ?

и если

при вызове по значению

val f = {(i) => {i * i}}:(Int) => Int # f: Int => Int = <function1>
является сокращением для
val f = {(i) => {i * i}}:Function1[Int, Int] # f: Int => Int = <function1>

затем при вызове по имени
val f = {(i) => {i * i}}:(=>Int) => Int # f: (=> Int) => Int = <function1>
является сокращением для
? что ?

другими словами

, если (Int) => Int это сокращение для FUNCTION1 [Int, Int]

затем (=> Int) => Int является стенография для ? что ?

Спасибо!

ответ

1

Это не обсчитывать ни за что. Типы имен по типам имен. См. SLS 4.6.1, http://www.scala-lang.org/files/archive/spec/2.11/04-basic-declarations-and-definitions.html#by-name-parameters.

Это правда, что если вы посмотрите на полученный байт-код, вы увидите, что аргумент будет передан как Function0, но это детализация реализации на уровне байт-кода. На уровне языка типы по-имени - это не просто синтаксический сахар. Они являются фактическими типами (хотя они могут отображаться только как типы параметров, а не в других контекстах).

Смотрите также: Use of Scala by-name parameters

+0

Спасибо Сет. Я боялся, что это будет ответ, и, честно говоря, мне это не нравится. Для меня это языковая несогласованность. В любом случае, хорошо знать (по крайней мере, для текущей версии Scala версии 2.11.6), что такой эквивалентности не существует. (В настоящее время я изучаю Scala, пытаясь сохранить организованный материал, но в этом случае модель, которую я искал, не очень хорошо подходила) –

1

На уровне байт-кода, это сокращение для:

Function1[Function0[Int], Int] 

Если вы хотите вызвать такой Scala код с другого языка JVM, вам придется FULLFILL эту подпись.

См the source code for Function0, вы не найдете его в scaladoc

+0

Благодаря Chirlo, но, кажется, подпись для "FUNCTION1 [Function0 [Int], Int]" есть "(() => Int) => Int = ", а не " (=> Int) => Int = ". Scala не позволяет мне объявить это (даже не компилировать): «val f: Function1 [Function0 [Int], Int] = {(i) => {i * i}}" как эквивалент val f: (=> Int) => Int = {(i) => {i * i}}. Допустимым объявлением будет «val f: Function1 [Function0 [Int], Int] = {(i) => i()}», хотя это не эквивалент 1 к 1 –

+1

Я обновил свой ответ, который основан на генерируется байт-код. – Chirlo