관리 메뉴

hyeals study

[코틀린] 람다식 & 멤버 참조 본문

코틀린

[코틀린] 람다식 & 멤버 참조

hyeals 2020. 2. 21. 17:10

* 람다 식(lambda expression): 다른 함수에 넘길 수 있는 작은 코드 조각

  • 장점: 쉽게 공통 코드 구조를 라이브러리 함수로 뽑아낼 수 있음 (실제로 코틀린의 표준 라이브러리는 람다를 많이 사용함)
  • 사용 예시: 컬렉션 처리

* 수신 객체 지정 람다(lambda with receiver): 특별한 람다임. 람다 선언을 둘러싸고 있는 환경과는 다른 상황에서 람다 본문을 실행할 수 있음.


[람다 소개]

 

* 람다식을 사용하면 함수를 선언할 필요가 없고, 코드 블록을 직접 함수의 인자로 전달할 수 있음.

☞ 코드가 간결해짐

 

-예를 들어, 버튼 클릭에 따른 동작을 정의할 때 이벤트 처리를 하는 리스너를 추가해야 함. 

이 때 버튼 클릭 리스너onClick이라는 메소드가 들어있는 onClickListener를 구현해야 함.

 

람다식의 장점을 알아보기 위해 자바의 익명 내부 클래스와 비교를 할 것임.

 

자바 익명 내부 클래스로 리스너 구현 예시

 

코틀린 람다로 리스너 구현 예시

  • 한 눈에 봐도 앞서 본 자바의 익명 내부 클래스보다 코드가 간결해졌음을 알 수 있음. (실제로 하는 기능은 같음)

[람다 & 컬렉션]

 

* 코틀린에서 라이브러리 함수를 사용하면 컬렉션 검색을 하기 쉬움

 

예시) 사람들로 이뤄진 리스트에서 가장 연장자를 찾는 코드

 

람다로 컬렉션 검색 예시

  • Person 클래스: 사람의 이름, 나이를 저장하는 클래스
  • people: 사람의 정보로 이뤄진 리스트
  • maxBy 함수: 가장 큰 원소를 찾기위해 비교에 사용할 값을 돌려주는 함수를 인자로 받음 (모든 컬렉션에서 호출 가능)
  • {it.age}: maxBy 함수에게 비교에 사용할 값을 돌려주는 함수 → 컬렉션의 원소를 인자로 받아서 비교에 사용할 값을반환하는 함수 ( 여기에서는 Person 객체의 age 필드에 저장된 나이 정보를 반환함)
  • it: 컬렉션의 원소
  • people.maxBy {it.age}: people.maxBy(Person::age) 와 같음

출력 결과


[람다 식 문법]

- 람다: 값처럼 전달할 수 있는 동작의 모음

 

※ 람다 식 문법

람다 식 문법

  • 람다식은 항상 중괄호로 둘러싸여 있음
  • 화살표(->): 인자 목록과 람다 본문을 구분해줌
  • x: Int, y: Int 부분은 파라미터
  • x + y 부분은 람다 본문

람다식 변수 저장 예시
출력 결과

  • 위의 코드 처럼 람다식을 변수에 저장할 수 있음.

람다식 직접 호출 예시
출력 결과

  • 람다 식은 위의 코드 처럼 직접 호출할 수도 있음
  • 위 코드처럼 코드 일부분을 블록으로 둘러싸서 실행할 필요가 있을 때 run을 사용함
  • run: 인자로 받은 람다를 실행해주는 라이브러리 함수
  • 따라서 위의 코드를 run { println(42) } 로 바꿀 수 있음

아래의 코드는 앞서 본 연장자를 찾는 코드임

람다로 컬렉션 검색 예시

위의 코드에서 정식으로 람다식을 쓰면

people.maxBy{( p: Person -> p.age )} 가 됨.

  • 중괄호 안에 있는 코드: 람다식
  • 람다식: Person 타입의 값을 인자로 받아서 age를 반환함.
  • 이 식을 더욱 간결하게 할 수 있음.

<people.maxBy{( p: Person -> p.age )} 간결하게 하기>

  1. 코틀린에서 함수 호출 시 맨 뒤에 있는 인자가 람다식이면 그 람다를 괄호 밖으로 뺄 수 있음 그러므로 people.maxBy(){ p: Person -> p.age }로 바꿀 수 있음
  2. 이 코드처럼 람다가 어떤 함수의 유일한 인자이며, 괄호 뒤에 람다를 썼다면 호출 시 빈 괄호를 없애도 됨 그러므로 people.maxBy{ p: Person -> p.age}로 바꿀 수 있음
  3. 컴파일러는 람다 파라미터의 타입을 추론할 수 있음 그러므로 people.maxBy{ p -> p.age }로 바꿀 수 있음
  4. 마지막으로 람다의 파라미터 이름을 디폴트 이름인 it으로 바꿀 수 있음, 람다의 파라미터가 하나뿐이고 그 타입을 컴파일러가 추론할 수 있는 경우 it으로 바꿀 수 있음 그러므로 people.maxBy{ it.age }로 바꿀 수 있음

* 람다 본문이 여러 줄로 되어 있으면 맨 마지막에 있는 식이 람다의 결과 값이 됨.


[현재 영역에 있는 변수에 접근]

 

* 람다를 함수 안에 정의하면 함수의 파라미터 & 람다 정의의 앞에 선언된 로컬 변수를 람다에서 사용할 수 있음.


[멤버 변수]

 

* 코틀린에서 함수를 값으로 바꿀 수 있음. 이 때 이중 콜론(::)을 사용함

☞ ex) val getAge = Person::age

☞ 이 때 ::을 사용하는 식을 멤버 참조(member reference)라고 부름

 

* 여기서 Person::age는 앞서 본 예제인 아래의 코드에서 it.age 부분과 같다고 위에서 언급함.

람다로 컬렉션 검색 예시

 

* 멤버 참조는 프로퍼티나 메소드를 단 하나만 호출하는 함수 값을 만들어 줌.

 

<Person::age>

  • Person: 클래스
  • age: 멤버
  • :: 으로 클래스와 멤버 구분
  • { person: Person -> person.age } 와 같은 역할을 함. (저 식을 가장 간결하게 바꾸면 {it.age}가 됨을 앞서 설명했음)

* 최상위에 선언됐고 다른 클래스의 멤버가 아닌 함수나 프로퍼티를 참조할 수도 있음

최상위에 선언된 함수 참조 예시
출력 결과

 

 

 

본 게시물은 "Kotlin IN ACTION"을 참고함.

Comments