2016-01-03 2 views
1

Я пытаюсь изучить scala и понять разницу между функциями и методами.Как получить значение из анонимной функции в scala?

Вот очень простой код, который я написал -

scala> class C (acc:Int) { 
     | val minc = (acc + 1) 
     | val func = {() => acc += 3 } 
     | } 

    scala> val c1 = new C(3) 
     c1: C = [email protected] 

    scala> c1.minc 
     res2: Int = 4 

    scala> c1.func 
     res3:() => Int = <function0> 

Я понимаю, что результат вызова функции FUNC на реализованном объект c1 хранится в виде другого выражение RES3.

Однако я хочу, чтобы получить значение из анонимной функции() = акк +3, который находится внутри класса C.

Если я пытаюсь передать аргумент RES3 выражение Scala выдает ошибку

scala> res3(4) 
    <console>:11: error: too many arguments for method apply:()Int in trait Function0 
    res3(4) 
     ^

Как получить от этого ценность?

PS - Я только что начал с scala и не знаю, возможно ли это вообще или нет?

ответ

5

Это ваше определение func:

val func = {() => acc += 3 } 

Давайте посмотрим в РЕПЛ на то, что это тип func.

scala> val c1 = new C(3) 
val c1 = new C(3) 
c1: C = [email protected] 

scala> c1.func 
c1.func 
res29:() => Unit = <function0> 

На простом английском языке это означает, что «Func относится к функции, которая не принимает никаких аргументов и не возвращает значение.» Unit означает, что метод ничего не возвращает. Если вы используете Java, то он аналогичен void как возвращаемый тип. function0 означает, что он принимает 0 аргументов.

Далее, давайте рассмотрим неудачный вызов в вашем примере.

scala> c1.func(4) 
c1.func(4) 
<console>:10: error: too many arguments for method apply:()Unit in trait Function0 
       c1.func(4) 
        ^

Теперь, когда мы знаем, что метод подписи func, это сообщение об ошибке должно иметь больше смысла.Мы знаем, что func ссылается на функцию, которая не принимает аргументов, но в этом вызове вы попытались вызвать ее с помощью одного целочисленного аргумента. Поскольку вызов метода имеет слишком много аргументов, Scala корректно сообщает об этом как об ошибке.

Я не совсем уверен, что вы пытались сделать, передав 4 в качестве аргумента. Лучше всего предположить, что вы пытаетесь применить функцию для вычисления ее результата, добавив 3 в acc, а затем вернув ее вызывающему. Если я прав, то мы можем переопределить C как это:

class C(var acc:Int) { 
    val minc = (acc + 1) 
    val func =() => { 
    acc += 3 
    acc 
} 

scala> val c1 = new C(3) 
val c1 = new C(3) 
c1: C = [email protected] 

scala> c1.func() 
c1.func() 
res44: Int = 6 

Когда мы называем c1.func(), никаких аргументов не передается, поэтому он правильно соответствует определенному методу подписи.

Другая возможность заключается в том, что вы пытались параметризовать сумму приращения и передать 4 ему в вызове. Если это так, то вы можете сделать это:

class C(var acc:Int) { 
    val minc = (acc + 1) 
    val func = (delta: Int) => { 
    acc += delta 
    acc 
    } 
} 

scala> c1.func(4) 
c1.func(4) 
res45: Int = 7 

В этом случае, мы заявили, что анонимная функция принимает 1 аргумент типа Int, поэтому, когда мы проходим 4 в вызове метода, он правильно соответствует сигнатуру метода ,

0

Вы не объявляете анонимную функцию так, как думаете. Эта линия:

val func = {() => acc += 3 } 

Это фактически объявляет анонимные функции. Скобки - первая анонимная функция (которая не принимает аргументов), а вторая - функция () => acc += 3. Scala позволяет объявить анонимную функцию 0-arity, просто используя скобки. Если вы уронили те, вы будете иметь то, что вы хотите:

val func =() => acc += 3 

Как немного стороне записки, вы можете увидеть это в сигнатуре типа. Ваша текущая подпись для func является:

() => Int = <function0> 

Это функция, которая принимает аргументы 0 и возвращает целое число. Это не то, что вы хотите. Когда вы измените его на то, что я дал вам, вы получите это:

Int => Int = <function1> 

Теперь func принимает один аргумент, и целое, и возвращает другое целое число, которое является то, что вы хотели.

+0

Благодарим вас за разъяснение! Тем не менее, я все еще вижу ошибку, когда пытаюсь получить ценность из функции. класс с (согласно: Int) { вал MiNC = (соотв + 1) вал FUNC =() => соотв + 3 } вал c1 = новый C (5) c1.minc печати 6 но, c1.func prints res23:() => Int = Я ожидаю выход 8 из этого объекта. Есть ли какой-либо другой метод, который я должен использовать для получения значения из func? – GoldenPlatinum

Смежные вопросы