_ => 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.