Как будто вы пытаетесь получить доступ к объекту, который является null
. Рассмотрим ниже пример:
TypeA objA;
. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException
, что имеет смысл.
См. Также этот пример:
String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
В Javascript, например, функции рассматриваются как один и тот же смешанный тип, как и все остальные (int
, string
, float
, bool
). Таким образом, вы можете создавать функции «на лету», назначать их вещам и называть их позже. Это полезно, но не то, что вы хотите использовать, или вы будете путать всех, кто должен поддерживать ваш код после вас ...
Это какой-то код, с которым я играл, чтобы увидеть, насколько глубоко это отверстие кролика идет:
var x = new Object;
x.thingy = new Array();
x.thingy[0] = function(){ return function(){ return function(){ alert('index 0 pressed'); }; }; }
x.thingy[1] = function(){ return function(){ return function(){ alert('index 1 pressed'); }; }; }
x.thingy[2] = function(){ return function(){ return function(){ alert('index 2 pressed'); }; }; }
for(var i=0 ;i<3; i++)
x.thingy[i]()()();
В контексте CS лямбда-функция представляет собой абстрактную математическую концепцию, которая решает проблему символической оценки математических выражений. В этом контексте лямбда-функция такая же, как лямбда-член .
Но в языках программирования это нечто иное. Это фрагмент кода, который объявлен «на месте», и его можно передать как «первоклассного гражданина». Эта концепция оказалась полезной, так что она вошла в почти все популярные современные языки программирования (см. lambda functions everwhere post).
Пример lambda в Ruby выглядит следующим образом:
hello = lambda do
puts('Hello')
puts('I am inside a proc')
end
hello.call
Генерирует следующий вывод:
Hello
I am inside a proc
Я тоже это понял. Я попробовал это в JS с этим:
var addAndMult = function(x) {
return (function(y) {
return (function(z) {
return (x+y)*z;
});
});
};
Он добавляет 2 к 4, а затем результат получается на 6. Однако мне иногда трудно прочитать: (
Также я сделал интересную функцию для каждого:
var forEach = function(arr) {
return (function(x) {
for (var i=0; arr[i]; i++) {
x(arr[i]);
}
});
}
forEach ([1,2,3,4,5]) (console.log);
Этот метод будет итерация массива и выполнение действия - в случае печати на консоль. Теперь я тоже понимаю, почему labmdas являются мощными.
лямбда-исчисление является последовательной математической теорией замещения. В школьной математике можно видеть, например, x+y=5
в паре с x−y=1
. Наряду с путями манипулирования отдельными уравнениями также можно объединить информацию из этих двух, при условии, что подстановки с поперечным уравнением выполняются логически. Lambda calculus кодирует правильный способ выполнения этих подстановок.
Учитывая, что y = x−1
является действительной перестановкой второго уравнения, это: λ y = x−1
означает функцию, заменяющую символы x−1
символом y
. Теперь представьте себе применение λ y
к каждому члену в первом уравнении. Если термин y
, то выполните замену; в противном случае ничего не делать. Если вы сделаете это на бумаге, вы увидите, как применение λ y
сделает первое уравнение разрешимым.
Это ответ без какой-либо компьютерной науки или программирования.
Самый простой пример программирования, о котором я могу думать, исходит из http://en.wikipedia.org/wiki/Joy_ (programming_language) #How_it_works :
вот как квадратная функция может быть определен на императивном языке программирования (C):
int square(int x) { return x * x; }
Переменная x является формальным параметром, который заменяется фактическим значением, которое должно быть квадратично при вызове функции. В функциональном языке (схема) будет определена одна и та же функция:
(define square (lambda (x) (* x x)))
Это по-разному, но по-прежнему использует формальный параметр x таким же образом.
Добавлено: http://imgur.com/a/XBHub
Название «лямбда» - это просто исторический артефакт. Все, о чем мы говорим, это выражение, значение которого является функцией.
Простым примером (с использованием Scala для следующей строки) является:
args.foreach(arg => println(arg))
, где аргумент foreach
метод является выражением для анонимной функции. Вышеупомянутая строка более или менее такая же, как запись чего-то вроде этого (не совсем настоящий код, но вы получите эту идею):
void printThat(Object that) {
println(that)
}
...
args.foreach(printThat)
, за исключением того, что вам не нужно беспокоиться:
Как только вы привыкли к функциям значений, необходимость обойтись без них кажется такой же глупой, как требуется для обозначения каждого выражения, например:
int tempVar = 2 * a + b
...
println(tempVar)
вместо написания выражение, в котором оно вам нужно:
println(2 * a + b)
Точная нотация варьируется от языка к языку; Греческий язык не всегда требуется! ; -)
Мне нравится объяснение Lambdas в этой статье: Эволюция LINQ и ее влияние на дизайн C # . Это имело для меня большой смысл, поскольку он показывает реальный мир для Lambdas и создает его в качестве практического примера.
Их быстрое объяснение: Lambdas - это способ обработки кода (функций) в качестве данных.
Немного упрощенно: функция лямбда - это функция, которая может быть передана другим функциям и доступна для доступа к логике.
В синтаксисе C # лямбда часто компилируется в простые методы так же, как анонимные делегаты, но
Например, (в C # 3):
LinqToSqlContext.Where(
row => row.FieldName > 15 );
LinqToSql может читать эту функцию (x> 15) и преобразовывать ее к фактическому SQL для выполнения с использованием деревьев выражений.
Вышеприведенное утверждение становится:
select ... from [tablename]
where [FieldName] > 15 --this line was 'read' from the lambda function
Это отличается от обычных методов или анонимных делегатов (которые действительно являются манерами компилятора), потому что они не могут быть прочитаны .
Не все методы в C #, которые используют лямбда-синтаксис, могут быть скомпилированы в деревья выражений (т.е. фактические лямбда-функции). Например:
LinqToSqlContext.Where(
row => SomeComplexCheck( row.FieldName ) );
Теперь дерево выражений невозможно прочитать - SomeComplexCheck не может быть разбит. Оператор SQL будет выполняться без того, и каждая строка данных будет помещена через SomeComplexCheck
.
Функции Lambda не следует путать с анонимными методами. Например:
LinqToSqlContext.Where(
delegate ( DataRow row ) {
return row.FieldName > 15;
} );
У этого также есть встроенная функция, но на этот раз это просто магия компилятора - компилятор C # разделит это на новый метод экземпляра с автогенерированным именем.
Анонимные методы не могут быть прочитаны, и поэтому логика не может быть переведена так, как может, для лямбда-функций.
В компьютерном программировании лямбда - это часть кода (оператор, выражение или группа из них), которая принимает некоторые аргументы из внешнего источника. Это не всегда является анонимной функцией - у нас есть много способов их реализации.
У нас есть четкое разделение между выражениями, утверждениями и функциями, которые у математиков нет.
Слово «Функция» в программировании также различна - у нас есть «функция - это последовательность шагов» (от латинского «выполнить»). В математике это связано с корреляцией между переменными.
Функциональные языки стараются как можно ближе к математическим формулам, а их слова означают почти то же самое. Но на других языках программирования мы имеем разные.
Просто потому, что я не вижу здесь примера C ++ 11, я остановлюсь и опубликую этот хороший пример из здесь . После поиска это самый яркий пример, который я смог найти.
template<typename F>
void Eval( const F& f ) {
f();
}
void foo() {
Eval( []{printf("Hello, Lambdas\n");} );
}
void bar() {
auto f = []{printf("Hello, Lambdas\n"); };
f();
}
На вопрос был дан ответ полностью, я не хочу вдаваться в подробности.
Существует пример lambda (анонимная функция)
let f = |x: f32| -> f32 { x * x - 2.0 };
let df = |x: f32| -> f32 { 2.0 * x };
Когда я писал модуль Newton- Рафсона, он использовался как производная первого и второго порядка. (Если вы хотите узнать, что такое метод Ньютона-Рафсона, посетите « https://en.wikipedia.org/wiki/Newton%27s_method ».
Выход как следующий
println!("f={:.6} df={:.6}", f(10.0), df(10.0))
f=98.000000 df=20.000000
Для человека без comp-sci фона, что такое лямбда в мире компьютерных наук?
Я проиллюстрирую его интуитивно шаг за шагом в простой и понятной форме python.
Короче говоря, лямбда - это просто анонимная и встроенная функция.
Давайте начнем с назначения, чтобы понять
lambdas
как первокурсник с фоном базовой арифметики.Схема присвоения - это «имя = значение», см.:
In [1]: x = 1 ...: y = 'value' In [2]: x Out[2]: 1 In [3]: y Out[3]: 'value'
«x», «y» - это имена и 1, «значение» - значения. Попробуйте функцию в математике
In [4]: m = n**2 + 2*n + 1 NameError: name 'n' is not defined
Отчеты об ошибках, вы не можете написать математику непосредственно в качестве кода, «n» должно быть определено или присвоено значению.
In [8]: n = 3.14 In [9]: m = n**2 + 2*n + 1 In [10]: m Out[10]: 17.1396
Теперь он работает, что если вы настаиваете на объединении двух линий seperarte с одним. Наступает
lambda
In [13]: j = lambda i: i**2 + 2*i + 1 In [14]: j Out[14]: <function __main__.<lambda>>
Не сообщалось об ошибках.
Это взгляд на
lambda
, он позволяет вам написать функцию в одной строке, как вы это делаете в математически в компьютер.Мы увидим это позже.
Давайте продолжим углубляться в «присвоение».
Как показано выше, символ равенства
=
работает для простых данных (1 и «значение») и простого выражения (n ** 2 + 2 * n + 1).Попробуйте следующее:
In [15]: x = print('This is a x') This is a x In [16]: x In [17]: x = input('Enter a x: ') Enter a x: x
Он работает для простых операторов, в python 7 имеется 11 типов. Простые инструкции - Документация Python 3.6.3
Как насчет составной инструкции,
In [18]: m = n**2 + 2*n + 1 if n > 0 SyntaxError: invalid syntax #or In [19]: m = n**2 + 2*n + 1, if n > 0 SyntaxError: invalid syntax
Наступает
def
включить ее работуIn [23]: def m(n): ...: if n > 0: ...: return n**2 + 2*n + 1 ...: In [24]: m(2) Out[24]: 9
Tada, проанализируйте его, 'm' - это имя, 'n ** 2 + 2 * n + 1' является значением.
:
является вариантом '='.Теперь вернемся к
lambda
, у нас есть функция с именем «m»Попробуйте:
g23]
In [28]: m = m(3) In [29]: m Out[29]: 16
Здесь есть два имени «m», функция
m
уже имеет имя, дублируется.Это форматирование:
In [27]: m = def m(n): ...: if n > 0: ...: return n**2 + 2*n + 1 SyntaxError: invalid syntax
Это не умная стратегия, поэтому отчеты об ошибках
Мы должны удалить одну из них, установить функцию без имени.
m = lambda n:n**2 + 2*n + 1
Это называется «анонимная функция»
В заключение,
lambda
в встроенной функции, которая позволяет вам написать функцию в одной прямой так же, как в математикеlambda
, АнонимНадеюсь, это поможет.
@Brian Я все время использую lambdas в C #, в операциях LINQ и non-LINQ. Пример:
string[] GetCustomerNames(IEnumerable<Customer> customers)
{ return customers.Select(c=>c.Name);
}
До C # я использовал анонимные функции в JavaScript для обратных вызовов для функций AJAX до того, как был введен еще один термин Ajax:
getXmlFromServer(function(result) {/*success*/}, function(error){/*fail*/});
Интересная вещь с C # лямбда-синтаксис заключается в том, что их собственный тип не может быть выведен (т. е. вы не можете вводить var foo = (x, y) => x * y), но в зависимости от того, к какому типу они назначены, ll быть скомпилирован как делегаты или абстрактные синтаксические деревья, представляющие выражение (так как магические объекты объектов LINQ выполняют свою «встроенную в язык» магию).
Lambdas в LISP также может быть передан оператору котировки, а затем пройден как список списков. Некоторые мощные макросы сделаны таким образом.
Лямбда - это тип функции, определенный в строке. Наряду с лямбдой вы также обычно имеете какой-то тип переменной, который может содержать ссылку на функцию, лямбда или иначе.
Например, вот кусок кода C #, который не использует лямбда:
public Int32 Add(Int32 a, Int32 b)
{
return a + b;
}
public Int32 Sub(Int32 a, Int32 b)
{
return a - b;
}
public delegate Int32 Op(Int32 a, Int32 b);
public void Calculator(Int32 a, Int32 b, Op op)
{
Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}
public void Test()
{
Calculator(10, 23, Add);
Calculator(10, 23, Sub);
}
Это вызывает калькулятор, передавая не только два числа, но и какой метод вызывать внутри калькулятора для получения результатов вычисления.
В C # 2.0 мы получили анонимные методы , который сокращает код выше:
public delegate Int32 Op(Int32 a, Int32 b);
public void Calculator(Int32 a, Int32 b, Op op)
{
Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}
public void Test()
{
Calculator(10, 23, delegate(Int32 a, Int32 b)
{
return a + b;
});
Calculator(10, 23, delegate(Int32 a, Int32 b)
{
return a - b;
});
}
И затем в C # 3.0 мы получили lambdas, который делает код еще короче:
public delegate Int32 Op(Int32 a, Int32 b);
public void Calculator(Int32 a, Int32 b, Op op)
{
Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}
public void Test()
{
Calculator(10, 23, (a, b) => a + b);
Calculator(10, 23, (a, b) => a - b);
}
Op
можно просто использовать Func<int, int>
– Mateen Ulhaq
14 May 2016 в 04:03
Console.WriteLine("Calculator: op " + op.Method.Name + " (" + a + ", " + b + ") = " + op(a, b));
для первого примера.
– Marc.2377
1 April 2017 в 00:53
Вы можете представить это как анонимную функцию - вот еще информация: Википедия - Анонимная функция
Вопрос формально ответил на многое, поэтому я не буду пытаться добавить больше об этом.
В очень простых, неформальных словах кому-то, кто знает очень мало или ничего по математике или программированию, я бы объяснил он как небольшая «машина» или «ящик», которая принимает некоторый вклад, делает некоторую работу и производит некоторый вывод, не имеет определенного имени, но мы знаем, где она находится и только этим знанием мы используем ее.
Практически говоря, для человека, который знает, что такое функция, я бы сказал им, что это функция, которая не имеет имени, обычно помещается в точку в памяти, которая может использоваться только путем ссылки на эту память (обычно через использование переменной - если они слышали о концепции указателей на функции, я бы использовал их в качестве аналогичной концепции) - этот ответ охватывает довольно основные (без упоминания о закрытии и т. д.), но можно легко получить смысл.
У меня проблемы с объявлением лямбда-выражения, потому что я работаю в Visual FoxPro, у которого есть подстановка Macro и функции ExecScript {} и Evaluate (), которые, похоже, выполняют ту же самую цель.
? Calculator(10, 23, "a + b")
? Calculator(10, 23, "a - b");
FUNCTION Calculator(a, b, op)
RETURN Evaluate(op)
Одно из преимуществ использования формальных lambdas - это (я предполагаю) проверка времени компиляции: Fox не будет знать, если вы опечатаете текстовую строку выше, пока она не попытается ее запустить.
Это также полезно для управляемого данными кода: вы можете хранить целые процедуры в полях memo в базе данных, а затем просто оценивать их во время выполнения. Это позволяет вам настроить часть приложения без фактического доступа к источнику. (Но это совсем другая тема.)
Это функция, которая не имеет имени. Напр. в c # вы можете использовать
numberCollection.GetMatchingItems<int>(number => number > 5);
, чтобы вернуть числа, которые больше 5.
number => number > 5
здесь лямбда-часть. Он представляет функцию, которая принимает параметр (число) и возвращает логическое значение (число> 5). Метод GetMatchingItems использует эту лямбду для всех элементов коллекции и возвращает соответствующие элементы.
Он относится к лямбда-исчислению , который является формальной системой, которая имеет только лямбда-выражения, которые представляют собой функцию, которая принимает функцию для своего единственного аргумента и возвращает функцию. Все функции в лямбда-исчислении имеют такой тип, т. Е. λ : λ → λ
.
Лисп использовал концепцию лямбда, чтобы назвать ее анонимные литералы функции. Эта лямбда представляет собой функцию, которая принимает два аргумента: x и y и возвращает их произведение:
(lambda (x y) (* x y))
Его можно применять в строке, как это (оценивается как 50 ) :
((lambda (x y) (* x y)) 5 10)