Я знаю, что обсуждение функций и методов хорошо избито, поэтому я постараюсь быть кратким. Я хочу показать крошечный блок кода и получить обратную связь:Рекурсивная функция/метод Scala - поиск окончательного ответа на то, что это такое
- Это метод, функция, то и другое, что-то еще?
- Если это способ, можно ли его превратить в функцию? (кроме как по значению f = m _)
- Есть ли более идиоматические способы сделать то, что я пытаюсь в этом примере?
Когда я вижу документы на методы, которые мы видим следующее:
def m(a:Int, b:Int):Int = { a + b }
В поисках функций мы видим:
(a:Int, b:Int) => a + b OR
val f:(Int,Int) => Int = (a, b) => a + b
Однако, когда мы копаться в recursive functions
мы почти всегда видим:
@tailrec def countStrings(a:List[String], b:Int = 0):Int = {
if (a == Nil) b
else countStrings(a.tail, b + 1)
}
countStrings: (a: List[String], b: Int)Int
Итак, на основе что я читал о методах, приведенный выше рекурсивный счетчик строк - это рекурсивный метод, а не функция. Теперь, если мы перепишем это в виде функции в соответствии с тем, как документы говорят нам, чтобы написать функции:
val countStrings:(List[String],Int) => Int = (a,b) => {
if (a == Nil) b
else countStrings(a.tail, b + 1)
}
countStrings: (List[String], Int) => Int = <function2>
Так что мой вопрос именно так: Является ли следующий блок помечается @tailrec
функцию, метод, как , или что-то другое?
@tailrec def countStrings(a:List[String], b:Int = 0):Int = {
if (a == Nil) b
else countStrings(a.tail, b + 1)
}
Кроме того, извинения, если это дубликат, я искал и, как и большинство вещей Скале, обнаружили противоречивые мнения по этому вопросу. Поэтому я надеюсь представить чрезвычайно простой пример и получить окончательный ответ. Спасибо.
Неофициально термины взаимозаменяемы. Менее неофициально, 'def m' означает член, который имеет тип метода. Значение 'val f' может быть типа' Function', где значение может быть буквальным '_ => 42' или' m _' и т. Д. –
Я верю, что ответ на ваш последний вопрос: это метод. Функции - это объекты с методом 'apply()', это не так. Вы можете изменить метод на функцию, используя расширение eta и afaik, есть два пути: сначала вы говорите «val f = m _», другое - «val f: Int => Int = m'. Поэтому, если компилятор знает, что ему нужна функция, он сможет расширять его без вашего явного подчеркивания. –
Если вы измените 'countStrings()' так, чтобы он больше не был рекурсивным, компилятор сообщает нам: 'error: не удалось оптимизировать @tailrec annotated' ** method **' countStrings' – jwvh