_ => Lambda 표현식에서이 밑줄은 무엇을 의미합니까?


111

람다 식은 _=> expr무슨 뜻인가요?

_람다에 대한 입력 의 목적은 무엇입니까 ?

예:

int count = 0;
list.ForEach(_ => count += 1);

8
안녕하세요, StackOverflow에 오신 것을 환영합니다. 유용한 답변을 얻을 가능성을 높이기 위해 질문을 약간 편집 할 수있는 자유를 얻었습니다.
Lasse V. Karlsen

그 주, 가정은 list이다 IEnumerable<T>, 그들은 수 (그리고해야한다) 만 사용했다sum = list.Count();
BlueRaja - 대니 Pflughoeft

충돌을 일으킬 수있는 다른 곳에서 사용될 수있는 새 변수 이름으로 범위를 "오염"시키는 것을 방지하는 데 사용할 수 있다고 생각합니다.
Tim Schmelter

답변:


84

매개 변수에 신경 쓰지 않을 때 사용되는 규칙입니다.


3
Haskell 및 기타 기능 언어에서 더 일반적입니다. 나는 그것이 어디에서 왔는지 생각합니다.
Gabe Moothart

10
Haskell, ML, Scala 및 기타 _에서 패턴 일치의 와일드 카드 문자입니다. 그것은 기본적으로 "상관 없어, 나는 항상 이것이 일치하기를 원한다"는 의미입니다. 이 "I do n't care"는 당신이 신경 쓰지 않는 것들을 명명 할 때 이어지고, 거기에서 다른 프로그래밍 언어로 넘쳐납니다. 예를 들어, Ruby _에서는 특별한 의미가 전혀 없지만 이 예제에서와 같은 의미로 Ruby에서도 사용됩니다 .
Jörg W Mittag

@ JörgWMittag 2010 년 5 월에 사실이지만 2010 년 6 월에는 그렇지 않습니다. 멋진 타이밍입니다! :) stackoverflow.com/q/6397078/38765
Andrew Grimm

38

유용한 이름은 아니지만 매개 변수 이름이지만, 컴파일 할 코드를 얻기 위해 표현식 에 매개 변수 있음을 지정해야 할 때 일반적으로 사용되는 이름입니다 (일부 규칙에 따라) .하지만 실제로는 신경 쓰지 않습니다. 그래서 당신은 그것을 무시할 것입니다.

기본적으로 C #의 유효한 식별자가 구성하는 구문을 악용하고 있으며 식별자는 밑줄로 시작할 수 있고 다른 것은 포함 할 수 없으므로 매개 변수 이름 일뿐입니다.

다음과 같이 쉽게 작성할 수 있습니다.

var _ = 10;

1
_ 대신 () 사용할 수 있습니까?
amesh

2
그것을 사용해 보셨습니까?
Lasse V. Karlsen

예, 람다 식을 사용하여 스레드를 만들 때 사용했습니다. Thread t= new Thread(()=>doSomething(x,y)); t.start();
amesh

내가 가정하는 것은 _ 사용은 사용되지 않더라도 컬렉션의 각 변수를 람다 식에 전달하는 것입니다. 그러나 ()을 사용하면 발생하지 않을 수 있습니다. 매개 변수가 적은 람다를 의미합니다.
amesh

ForEach 메서드 호출을 사용하여 시도해야합니다. 매개 변수를 사용하지 않는 대리자를 사용하는 Thread 생성자에 오버로드가 있습니다. 대신 매개 변수를 취하는 대리자를 취하는 ForEach와 같은 메소드를 호출 해보십시오.
Lasse V. Karlsen


10

람다 표현은 대부분 짧고 익명의 코드에서 사용되기 때문에 변수의 이름이 때때로 필요하지 않을 수 있습니다. 심지어 코드 블록에서 변수를 사용하지 않더라도 짧은 규칙에 _를 제공합니다.


7

나는 또한 _ => _.method()지시의인지 적 무게를 감소시키기 때문에 한 줄의 메서드 호출 람다 에 대한 사용을 두 번째로 사용 합니다. 특히 제네릭을 사용할 때 작성 x => x.method()하면 "이 'x'는 무엇입니까? 공간의 좌표입니까?"라는 순간적인 고려 사항이 추가됩니다.

다음 경우를 고려하십시오.

Initialize<Client> ( _=>_.Init() );

Generics 호출과 함께 사용되며이 경우 밑줄은 "우회 기호"로 작동합니다. 중복을 방지하고 인수의 유형이 명확하고 사용에서 유추 될 수 있음을 정의합니다. 이는 유형 선언을 반복하지 않도록 'var'를 사용할 때와 같습니다. client=>client.Init()여기에 쓰면 의미를 추가하지 않고 지침이 길어집니다.

분명히 이것은 설명 적으로 이름을 지정해야하는 메서드에 전달할 매개 변수에는 적용되지 않습니다. 예 :Do( id=>Log(id) );

람다 식별자가 제네릭 정의에서 연결이 끊어지기 때문에 한 줄 대신 코드 블록을 사용하는 경우 메서드 호출에 대한 단일 밑줄 매개 변수 사용은 거의 정당화 할 수 없습니다. 일반적으로 동일한 식별자를 재사용하려면 설명이 포함 된 이름을 지정하십시오.

요점은, 특히 익명 대리자 생성을 단순화하기 위해 만들어진 람다의 경우, 자세한 내용은 명확성을 위해서만 정당화 될 수 있다는 것입니다. 어쨌든 가독성과 간결함의 균형을 유지하면서 상식을 사용해야합니다. 기호가 실제 기능에 대한 "후크"일 경우 하나의 문자 식별자는 완벽합니다. For-loops와 "i"및 "j"문자가 인덱서로 사용되는 경우입니다.


2
이 접근 방식에 +1! 나는 람다에서 밑줄을 사용하여 "인지 적 가중치를 줄이면서"이 매개 변수가 사용되지 않음을 보여주는 유일한 사람 이었지만. 특히 LINQ 쿼리의 경우와 같이 많은 연결이 있고 유형을 즉시 유추 할 수있는 경우 밑줄로 더 쉽게 읽을 수 있습니다.
Varvara Kalinina

3
Do(id => Log(id))Do(Log).
Aluan Haddad
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.