В моих поисках для понимания очень нечетного взгляда '=>' оператор я нашел, что хорошее место запускается, и автор очень краток и ясен:
parameters => expression
У кого-либо есть какие-либо подсказки относительно понимания основ лямбд так, чтобы стало легче 'дешифровать' более сложные операторы лямбды?
Например: если мне дают что-то как (из ответа, я получил здесь):
filenames.SelectMany(f =>
Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
.Cast()
.Select(a => a.PluginType)
).ToList();
Как я могу пойти о разламывании этого на более простые части?
ОБНОВЛЕНИЕ: требуемый для показа моего первого лямбда-выражения. Не смейтесь надо мной, но я сделал это, не копируя чей-то пример..., и это работало в первый раз:
public ModuleData[] GetStartModules( )
{ return modules.FindAll(start => start.IsBatch == true).ToArray(); }
Давайте рассмотрим образец вашего кода:
filenames.SelectMany(f =>
Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
.Cast<PluginClassAttribute>()
.Select(a => a.PluginType)
).ToList();
Итак, мы начнем с β string []
, называемых именами данных
. Мы вызываем метод расширения
на массиве, а затем мы вызываем SelectMany
SelectMany TOLIST
в результате:
filenames.SelectMany(
...
).ToList();
SelectMany
принимает делегат в качестве параметра, в этом случае делегат должен Возьмите один параметр типа string
в качестве ввода и возврата IENumerable
(где выводится тип t
). Это где лямбдас вступает в сцену:
filenames.SelectMany(f =>
Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
).ToList()
Что произойдет вот то, что для каждого элемента в массиве в массиве
делегат будет вызван. F
- это входной параметр, и все, что подойдет справа от =>
- это тело метода, который делегат относится к. В этом случае Assembly.load from
будет вызывать имя файла в массиве, передавая его имя файла в метод loadFrom
, используя аргумент f
. В состав будет возвращено
getCustomattribute (typeof (pluginclassattribute), true)
, что возвращает атрибут Array
. Таким образом, компилятор не может сделать вывод, что тип T
, упомянутых ранее, является ,
.
на IENumerable
, который возвращается, будет включен
, будет вызван
()
, возвращается Ienumerable
.
Итак, теперь у нас есть IENumerable
, и мы вызовите . Выберите на нем
. SELECT
метод аналогичен SelectMany
, но возвращает один экземпляр типа T
(который выводится компилятором) вместо IENumerable < T>
. Настройка идентична; Для каждого элемента в Ienumerable
он будет вызывать определенный делегат, передавая значение текущего элемента в него:
.Select(a => a.PluginType)
снова, A
- это входной параметр, A.PlugIntype
- это тело метода. Итак, для каждого PluginClassattribute
экземпляра в списке он вернет значение свойства PluclintyPe
(я буду предположить, что это свойство имеет тип типа
).
Резюме
Если мы приклеиваем эти биты и куски вместе:
// process all strings in the filenames array
filenames.SelectMany(f =>
// get all Attributes of the type PluginClassAttribute from the assembly
// with the given file name
Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
// cast the returned instances to PluginClassAttribute
.Cast<PluginClassAttribute>()
// return the PluginType property from each PluginClassAttribute instance
.Select(a => a.PluginType)
).ToList();
Lambdas против делегатов
давайте закончим это, сравнивая лямбдас для делегатов. Возьмите следующий список:
List<string> strings = new List<string> { "one", "two", "three" };
скажем, мы хотим отфильтровать те, которые начинаются с буквы «T»:
var result = strings.Where(s => s.StartsWith("t"));
Это самый распространенный подход; Установите его, используя лямбда выражение. Но есть альтернативы:
Func<string,bool> func = delegate(string s) { return s.StartsWith("t");};
result = strings.Where(func);
Это, по сути, то же самое: сначала мы создаем делегат типа FUNC
(это означает, что он требует строки
в качестве входного параметра, и возвращает A Bool
). Затем мы проходим этот делегат в качестве параметра к , где метод
. Это то, что компилятор сделал для нас за кулисами в первом образце ( строк. Где (S => S.ctartswith («T»));
).
Один третий вариант - просто передавать делегату к неанонимному методу:
private bool StringsStartingWithT(string s)
{
return s.StartsWith("t");
}
// somewhere else in the code:
result = strings.Where(StringsStartingWithT);
Итак, в том случае, если мы смотрим здесь, выражение лямбда - довольно компактный способ определения делегата, как правило, ссылаясь на Анонимный метод.
И если у вас была энергия, прочитала все, что здесь, ну, спасибо за ваше время :)
Вычисление лямбды распространено во многих языках программирования. В некоторых языках их также называют анонимными функциями. Хотя разные языки имеют разный синтаксис лямбда, принцип один и тот же, и их различные части обычно одинаковы.
Возможно, наиболее известной из них являются анонимные функции Javascript.
lol = function() {laugh()}
# is equivalent to
function lol() {laugh()}
В чем разница? Ну, иногда не хочется создавать функцию только для того, чтобы раз и навсегда передать ее куда-нибудь.
window.onload = function() {laugh()}
# is way easier than
function lol() {laugh()}
window.onload = lol
Вы можете посмотреть статью в википедии для неразборчивой информации или вы можете перейти непосредственно к Lambda в программировании в той же статье.
AurioTouch - правильный пример. К сожалению, код просто ужасен. Убедитесь, что он используется только для ознакомления с концепциями работы с аудиоустройством RemoteIO.
Фактическое рисование формы сигнала происходит прямо в обратном вызове renderProc, который вызывается CoreAudio, когда становятся доступными данные PCM. Посмотрите на PerformThru () в aurioTouchAppDelegate.mm:197... далее вниз, в строке 237
SInt8 *data_ptr = (SInt8 *)(ioData->mBuffers[0].mData);
... здесь осуществляется доступ к фактическим данным ИКМ. Это данные, которые необходимо проанализировать для получения пиковой/средней мощности сигнала.
-121--3653551-Написанный запрос выбирает атрибут f. Однако возвращать узел атрибута из XQuery недопустимо. Ошибка ссылается на выходной документ, который здесь содержит только атрибут (хотя это сообщение об ошибке вводит в заблуждение, так как технически здесь нет выходного документа, то возвращается только узел атрибута).
Вы, вероятно, хотели бы вернуть значение атрибута, а не самого атрибута
return data($foonode)
-121--2207907- Одно хорошее простое объяснение, направленное на разработчиков, которые тверды в кодировании, но не в lambdas, это простое видео на TekPub
TekPub - Концепции: # 2 Lambdas
Вы
Я понимаю, что этот старый вопрос, но он может быть полезным.
map.with_options(:path_prefix => ":locale") do |m|
m.resources :posts
m.resources :stories
end
И вы должны добавить перед фильтром к контроллеру приложения, чтобы определить язык, например,
before_filter :define_locale
def define_locale
if params[:locale] == nil
I18n.locale = 'en'
else
I18n.locale = params[:locale]
end
end
-121--1625201- С точки зрения базы данных вы должны быть более точными. Это RDBMS, ODBMS или большая сохраняемая хэш-таблица? Для меня файловая система также является своего рода "реализацией базы данных" (на основе иерархии и каталога/файла).
-121--4667703-Итак, начать с страшного определения - лямбда - это еще один способ определения анонимного метода. Существует (с C # 2.0 я полагаю) способ построения анонимных методов - однако, что синтаксис был очень... неудобный.
Что такое анонимный метод? Это способ определения метода в линию, без имени - следовательно, анонимно. Это полезно, если имеется метод, который принимает делегат, так как можно передать лямбда-выражение/анонимный метод в качестве параметра, учитывая, что типы совпадают. Возьмем IEnumerable.Select в качестве примера, он определяется следующим образом:
IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);
Если этот метод обычно используется в списке и каждый элемент выбирается дважды (что связано с самим собой):
string MyConcat(string str){
return str + str;
}
...
void myMethod(){
IEnumerable<string> result = someIEnumerable.Select(MyConcat);
}
Это очень неудобный способ сделать это, особенно если вы хотите выполнить многие из этих операций - также обычно такие методы вы используете только один раз. Показанное определение (parameters = > expression) очень смыслово и попадает в пятно. Интересным в лямбде является то, что не нужно выражать тип параметров - , пока они могут быть выведены из выражения . Т.е. в случае Select - мы знаем , что первый параметр должен иметь тип TSource - потому что определение метода так и утверждает. Дальше больше - если мы назовем метод так же, как foo. Выберите (...), затем возвращаемое значение выражения определит TResult.
Интересно также то, что для лямбды с одним оператором не требуется ключевое слово return - лямбда возвращает все, что вычисляет одно выражение. Однако если используется блок (заключенный в "" {"" и ""} ""), необходимо включить ключевое слово return, как обычно.
Если вы хотите, по-прежнему 100% законно определять типы параметров. С этим новым знанием попробуем переписать предыдущий пример:
void myMethod(){
IEnumerable<string> result = someIEnumerable.Select(s => s + s);
}
Или, с явными параметрами, заявленными
void myMethod(){
IEnumerable<string> result = someIEnumerable.Select((string s) => s + s);
}
Еще одна интересная особенность лямбды в C # - их использование для построения деревьев выражений . Это, вероятно, не "начинающий" материал, но короче говоря, дерево выражений содержит все метаданные о лямбде, а не исполняемый код.
Ну, лямбда может показаться вам быстрым способом написания метода, который вы хотите использовать только один раз. Например, следующий метод
private int sum5(int n)
{
return n + 5;
}
эквивалентен лямбде: (n) => n + 5
. Кроме того, что метод можно вызвать где угодно в классе, а лямбда живет только в объявленной области видимости (можно также хранить лямбды в объектах Action и Func)
Другая вещь, которую лямбды могут сделать для вас, это захват области видимости, построение закрытия. Например, если у вас есть что-то подобное:
...methodbody
int acc = 5;
Func<int> addAcc = (n) => n + acc;
То, что у вас есть, есть функция, которая, как и раньше, принимает аргумент, но добавляемая сумма берётся из значения переменной. лямбда может жить даже после того, как будет закончена область видимости, в которой была определена acc.
С помощью лямбда можно строить очень аккуратные вещи, но нужно быть осторожным, потому что иногда вы теряете читабельность с помощью таких хитростей.
Мой совет для понимания Основы лямбдас - это два раза.
Во-первых, я рекомендую узнать о функциональном программировании. Haskell - хороший язык, чтобы начать с этим уважением. Книга, которую я использую, и вы получаете много, это программирование в Haskell Graham Hutton. Это дает хорошее заземление в Haskell и включает в себя объяснения лямбдаса.
Оттуда я думаю, что вы должны просмотреть лекции Эрика Мейера на функциональном программировании , так как они дают отличное введение в функциональное программирование, а также используя Haskell и пересекать в C #.
Как только вы взяли во все, что вы должны быть хорошо на пути к пониманию лямбдаса.
Аннотация метода @ ModelAttribute
предназначена для предоставления ссылочных данных слою представления. Я не могу сказать точно в вашем случае, но я бы не сказал, что коллекция пользователей квалифицирована как справочные данные. Рекомендуется явно передать эту информацию модели в методах обработчика @ RequestMapping
.
Если вы по-прежнему хотите использовать @ ModelAttribute
, здесь есть запись блога , в которой обсуждается проблема перенаправления.
Но все предыдущие примеры имеют общая проблема, как all @ ModelAttribute методы выполняются до того, как обработчик выполнено, если обработчик возвращает перенаправление данных модели будет добавлено в URL-адрес в виде последовательности запроса. Это следует избегать любой ценой, как это может раскрыть некоторые секреты о том, как вы собрали вашу заявку.
Предложенное им решение (см. часть 4 блога) заключается в использовании HandableIntercepterAdapter
, чтобы сделать общие ссылочные данные видимыми для просмотра. Поскольку эталонные данные не должны быть тесно связаны с контроллерами, это не должно создавать проблем с точки зрения конструкции.
$ знак не является частью javascript он является частью javascript рамки вероятно, jQuery
Дополнительные сведения см. в этой статье
-121--2873411-В последнее время у CodeProject была хорошая вводная статья: C # Делегаты, анонимные методы и лямбда-выражения - O My!
Как сказал другие, выражение лямбда - это запись для функции. Это связывается бесплатные переменные в правой части выражения к параметрам слева.
a => a + 1
Создает функцию, которая связывает свободную переменную A в выражении (A + 1) к первому параметру функции и возвращает эту функцию.
Один случай, когда лямбдас чрезвычайно полезен, заключается в том, что вы используете их для работы со структурами списка. Класс System.linq.enumerable предоставляет много полезных функций, которые позволяют работать с выражениями лямбда и объектами, реализующими iEnumerable. Например, перечисление. Где можно использовать для фильтрации списка:
List<string> fruits = new List<string> {
"apple", "passionfruit", "banana", "mango",
"orange", "blueberry", "grape", "strawberry" };
IEnumerable<string> shortFruits = fruits.Where(fruit => fruit.Length < 6);
foreach (string fruit in shortFruits) {
Console.WriteLine(fruit);
}
Выход будет «Apple, Mango, Grape».
Старайтесь понять, что здесь происходит: фрукт выражения => фрукты. <6 создает функцию, которая возвращает true , если свойство длины параметра составляет менее 6 6
. В течение списка и создает новый список, который содержит только те элементы, для которых прилагаемая функция возвращает true. Это сохраняет вас для записи кода, который итерации по поводу списка, проверяет предикат для каждого элемента и делает что-то.
Это просто обозначение C #, чтобы записать значение функции. Это не требует отдачи функции имя, поэтому это значение иногда называют анонимной функцией . Другие языки имеют другие обозначения, но они всегда содержат список параметров и тело.
Оригинальное нотация, изобретенное Церковью Алонзо для его лямбда-исчисления в 1930-х годах использовала греческий характер лямбда в выражении λx.t
, чтобы представлять функцию Отсюда и название.