Поиск…


замечания

Scala делает все возможное, чтобы рассматривать методы и функции как синтаксически идентичные. Но под капотом они представляют собой разные понятия.

Метод является исполняемым кодом и не имеет представления значения.

Функция - это фактический экземпляр объекта типа Function1 (или аналогичный тип другой арности). Его код содержится в методе его apply . Фактически, он просто действует как ценность, которая может быть передана.

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

Фактическая функция более высокого порядка - это функция, которая либо принимает значение функции в качестве аргумента, либо возвращает значение функции. Но в Scala, поскольку все операции являются методами, более общее представление о методах, которые принимают или возвращают параметры функции. Таким образом, map , как определено в Seq может считаться «функцией более высокого порядка» из-за того, что ее параметр является функцией, но это не буквально функция; это метод.

Использование методов в качестве значений функций

Компилятор Scala автоматически преобразует методы в значения функций для передачи их в функции более высокого порядка.

object MyObject {
  def mapMethod(input: Int): String = {
    int.toString
  }
}

Seq(1, 2, 3).map(MyObject.mapMethod) // Seq("1", "2", "3")

В приведенном выше примере MyObject.mapMethod не является вызовом функции, а вместо этого передается для map в качестве значения. Действительно, для map требуется переданное ей значение функции, как видно из ее подписи. Подпись для map List[A] (список объектов типа A ):

def map[B](f: (A) ⇒ B): List[B]

Часть f: (A) => B указывает, что параметр этого вызова метода является некоторой функцией, которая принимает объект типа A и возвращает объект типа B A и B произвольно определены. Возвращаясь к первому примеру, мы видим, что mapMethod принимает Int (что соответствует A ) и возвращает String (что соответствует B ). Таким образом mapMethod является допустимым значением функции для перехода к map . Мы могли бы переписать тот же код, как это:

Seq(1, 2, 3).map(x:Int => int.toString)

Это добавляет значение функции, которое может добавить ясность для простых функций.

Функции высокого порядка (функция как параметр)

Функция более высокого порядка, в отличие от функции первого порядка, может иметь одну из трех форм:

  • Один или несколько его параметров являются функцией, и она возвращает некоторое значение.

  • Он возвращает функцию, но ни один из ее параметров не является функцией.

  • Оба перечисленного: один или несколько его параметров являются функцией, и она возвращает функцию.

    object HOF {
        def main(args: Array[String]) {
        val list = List(("Srini","E"),("Subash","R"),("Ranjith","RK"),("Vicky","s"),("Sudhar","s"))
        //HOF
         val fullNameList= list.map(n => getFullName(n._1, n._2))
    
         }
    
        def getFullName(firstName: String, lastName: String): String = firstName + "." + lastName
        }
    

Здесь функция map принимает функцию getFullName(n._1,n._2) в качестве параметра. Это называется HOF (функция высшего порядка).

Аргументы ленивой оценки

Scala поддерживает ленивую оценку аргументов функции с помощью нотации: def func(arg: => String) . Такой аргумент функции может принимать обычный объект String или функцию более высокого порядка с типом возвращаемого типа String . Во втором случае аргумент функции будет оцениваться при доступе к значениям.

См. Пример:

def calculateData: String = {
  print("Calculating expensive data! ")
  "some expensive data"
}

def dumbMediator(preconditions: Boolean, data: String): Option[String] = {
  print("Applying mediator")
  preconditions match {
    case true => Some(data)
    case false => None
  }
}

def smartMediator(preconditions: Boolean, data: => String): Option[String] = {
  print("Applying mediator")
  preconditions match {
    case true => Some(data)
    case false => None
  }
}

smartMediator(preconditions = false, calculateData)

dumbMediator(preconditions = false, calculateData)

вызов smartMediator возвращает значение None и печатает сообщение "Applying mediator" .

вызов dumbMediator возвращает значение None и выводит сообщение "Calculating expensive data! Applying mediator" .

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



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow