Реализации сильно отличаются от компилятора Scala. Кэрри версия компилирует к методу Java, убрав выделки параметров:
def f1(elem: Int, other: Int): Boolean = elem.==(other);
вторая версия представляет собой метод, который возвращает анонимную функцию (а Function1
), поэтому их подписи совершенно различны. Хотя они часто могут быть взаимозаменяемыми в Scala кода, есть немного больше сгенерированный код во второй версии:
def f2(elem: Int): Function1 = (new <$anon: Function1>(elem): Function1);
@SerialVersionUID(value = 0) final <synthetic> class anonfun$f2$1 extends scala.runtime.AbstractFunction1$mcZI$sp with Serializable {
final def apply(other: Int): Boolean = anonfun$f2$1.this.apply$mcZI$sp(other);
<specialized> def apply$mcZI$sp(other: Int): Boolean = anonfun$f2$1.this.elem$1.==(other);
final <bridge> <artifact> def apply(v1: Object): Object = scala.Boolean.box(anonfun$f2$1.this.apply(scala.Int.unbox(v1)));
<synthetic> <paramaccessor> private[this] val elem$1: Int = _;
def <init>(elem$1: Int): <$anon: Function1> = {
anonfun$f2$1.this.elem$1 = elem$1;
anonfun$f2$1.super.<init>();
()
}
}
Я бы только рассмотреть используя второй вариант в тех случаях, когда я был явно ищу работу с Function1
объектов. Тем не менее, я лично склоняюсь к использованию версии в карри, потому что вы все равно можете получить Function1
назад с частичным применением первого. Версия в карри также столь же мощна, но не создаст объекты Function1
, когда они вам не понадобятся.
scala> f1(1) _
res1: Int => Boolean = <function1>
благодарим за ответ. как вы производите Java-код из scala? также, что-то вроде 'val f3 = (_: Int) == (_: Int); f3.curried' страдают от той же проблемы, которую вы отметили с помощью 'f2'? –
Вы не можете создать четкий байт-код Java из Scala (но может генерировать байтовый код). Я использовал '-Xprint: jvm' для создания кода в моем ответе, который является одной из последних фаз компилятора Scala. 'f3.curried' создавал бы _two_ анонимные функции вместо одного, поэтому он выдавал бы более байт-код, чем' f2'. –