разница между передачей значения и передачей функции в качестве параметра в scala

Я часто слышу, что scala имеет возможность передать функцию в качестве параметра другой функции. Я хотел бы знать разницу между передачей значения в качестве параметра и передачей самой функции в качестве параметра. Как последний подход дает преимущество в программировании. Если функции передаются как параметр как создаются ссылки на объекты, поскольку функции не привязаны ни к каким объектам.

2 голоса | спросил prasonscala 1 PM00000010000000331 2011, 13:19:03

3 ответа


2

Вы когда-нибудь использовали шаблоны посетителя или стратегии, фабрики или инъекции зависимостей? Вы когда-нибудь проходили или просили объект типа Runnable или Comparator? Все эти вещи ad hoc взламывают недостающую способность передавать функции.

В шаблоне посетителя вместо accept получают интерфейс для посетителя, вместо этого вы выполняете функцию Element => Unit (для пустоты - вертушка). Общая концепция посетителя известна как катаморфизм , из которых все виды сопоставлений и складок являются особыми случаями из.

В шаблоне стратегии интерфейс стратегии - это просто функция. В примере wiki замените интерфейс (Int, Int) => Int.

В шаблоне фабричных методов весь заводский класс является функцией. В примере с инкапсуляцией wiki ImageReaderFactory есть только (InputStream) => ImageReader.

A Runnable - это просто функция () => Unit. A Comparator - это просто функция (A, A) => Int. Я мог бы продолжать и продолжать с этим, но достаточно сказать это: вы все время передавали функции как аргументы, просто трудный путь.

Что касается вашего последнего вопроса, я не очень хорошо понимаю, что вы имеете в виду. Функция в Scala - это объект, реализующий интерфейс FunctionN, где N представляет arity. Конечно, не-объектно-ориентированные языки не обязаны представлять функции как объекты. На самом деле даже объектно-ориентированные языки не привязаны к этому - int в Java не является объектом, поэтому зачем нужна функция?

ответил Daniel C. Sobral 1 PM00000060000001931 2011, 18:18:19
2

Lazy Evaluation

Преимущество - это способность выполнять Lazy Evaluation выражение, которое передается. Вместо того, чтобы вычислять реальное значение x во время передачи выражения. Оно может создать thunk, который откладывает выполнение до тех пор, пока его абсолютно необходимо.

Почему это полезно? Одним из примеров является то, что вы можете определить бесконечный список чисел с учетом выражения.

Пример (Haskell)

let fibs = map fst $ iterate(\(a,b) -> (b,a+b)) (1,2)

В этом случае значение fibs дается выражением, которое состоит из нескольких функций, в этом случае отображение f итерации (и анонимного выражения или лямбда).

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

let fibSum = sum fibs

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

Однако, если бы я использовал фиб с другим выражением

let fibsEvenSum = sum(takeWhile(< 4000000) (filter even fibs))

Эта сумма по-прежнему будет вызывать фибс для оценки, однако это приведет к завершению оценки, когда список достигнет 4 миллионов.

ответил Justin Shield 1 PM00000020000001831 2011, 14:07:18
0

Функции как параметры полезны многими многими способами. Рассмотрим шаблон прослушивателя /адаптера Java и общие ситуации, в которых необходимы обратные вызовы (API-интерфейсы, основанные на событиях). В Java, чтобы заставить графический интерфейс сделать что-то нажатием мыши или нажатием клавиши, вам потребуется реализовать весь соответствующий интерфейс прослушивателя (или расширить класс адаптера). Контрастируйте это, просто передав объект функции, который будет выполняться при щелчке мыши (вы можете увидеть это на C # с помощью своей системы событий). Это намного проще.

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

  • Семейство функций «notAny», «every», «any», «notEvery», которые все принимают параметр функции и параметр коллекции, и возвращают true, если [функция возвращает false для всех coll. elem.]
    [функция возвращает true для всех coll. elem.]
    [функция возвращает true для любого колла. elem.]
    [функция возвращает false для любого колла. эль]
    соответственно
  • Компаратор, который сравнивает результаты функции с элементами коллекции, например.
    новый FuncComparator (Person.getName) позволит вам сортировать коллекцию лиц по их имени.
  • функции, такие как «map», «filter», «groupBy», которые принимают параметр функции и коллекцию (ы) и создают новую коллекцию. Преобразование старого в новую коллекцию каким-то образом использует функцию параметра. Например:
    groupBy может взять функцию и коллекцию и вернуть карту списков, в которых списки содержат элементы исходной коллекции, для которых функция параметра возвращает одно и то же значение, и это значение является ключом карты.

Это всего лишь несколько случаев, когда общий алгоритм «перебирать коллекцию и делать X» значительно улучшен функциями как объекты первого класса, поскольку он позволяет определять X с помощью параметра функции. Тем не менее, это не все ... существует более сложное использование функций в качестве параметров (первоклассные функции), многие из которых включают в себя функции, которые генерируют функции. Вы должны посмотреть на язык программирования Clojure для примеров этих применений.

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

ответил U Mad 1 PM00000030000005331 2011, 15:24:53

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132