[유니티 중급]_3 람다식, Func 대리자

0

유니티 엔진

목록 보기
14/21

람다식

람다는 보통 작성한 곳에서 한번만 쓰는 일회성 함수(= 무명함수)를 만들때 사용합니다.
때문에 함수를 최대한 간결하게 표현하는것을 위해 만들어졌고
필요없는것을 제거하고 남은것이 '매개변수'와 '식' 입니다.

  • 람다식은 무명함수를 만들 수 있습니다.
  • 무명함수는 함수의 매개변수에 '값'이 아닌 '코드'자체를 넘기고 싶을 때 사용할 수 있습니다.
  • 람다식에서는 =>를 중심으로 왼편에는 매개변수가, 오른편에는 식이 위치합니다.
  • 람다식은 메소드를 더욱 간결하게 만들기 위해 형식유추 기능을 제공합니다.

매개변수_목록 => 식

매개변수 목록은 함수에서 쓰는 매개변수를 입력하면됩니다.
식은 함수에서 {} 안에 쓰는 로직을 입력하면됩니다.

함수를 람다식으로 표현

간단한 함수를 람다로 표현하면 가독성을 증가시킬 수 있습니다.

class FriendList
{
	private List<string> list = new List<string>();			//친구 리스트
	
	public void Add(string name) => list.Add(name);			//친구 추가
	public void Remove(string name) => list.Remove(name);	//친구 삭제
}

Func

델리게이트를 편리하게 사용하기 위해서 나온 문법이 Action 대리자와 Func 대리자입니다.
이전 시간에는 델리게이트 체인을 만들어서 이벤트로 사용했던 Action 대리자를 배웠습니다.

  • Func 대리자는 결과를 반환하는 메소드를 참조하기 위해 만들어 졌으며
    17개의 메소드가 오버로딩 되어있습니다.

  • Func 대리자는 Action과 달리 반드시 반환값을 return해야합니다.

  • Func 대리자는 람다식으로 간편하게 사용할때 이용합니다.

  • 매개변수의 데이터 형식으로 이용합니다.

테스트를 위해 Func 인스턴스를 생성했습니다.

접근 제한자를 용도에 맞게 설정하고,
Func<>괄호 안에 매개변수 개수에 맞춰 데이터 형식을 작성합니다.
(마지막 매개변수는 출력 전용 매개변수 out 입니다.)

매개변수를 넣지 않는다고 해도 항상 1개의 데이터 타입을 작성해야 하는데,
이 데이터 타입에는 반환값의 타입을 넣어야 합니다.

참고
두개 이상 부터는 항상 마지막 데이터 형식이 반환값의 타입입니다.
Func는 항상 마지막 데이터형식이 out이 되도록 오버로딩 되어있기 때문입니다.

예) int, int, int => 앞 int 두 개는 매개변수의 형식, 마지막 int는 반환값의 형식입니다.

그리고 Add함수와 Sub함수를 콜백함수로 등록시켜보겠습니다.
(Action과 마찮가지로 System을 using 선언해 줘야 합니다.)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using System;							// 필수!!

public class Func대리자 : MonoBehaviour
{
    public Func<int,int,int> myFunc;	//Func 인스턴스 생성

    void Start()
    {
        myFunc += Add;		//콜백함수 등록
        myFunc += Sub;		//콜백함수 등록

        int num = 0;
        num += myFunc(1, 2);		//인수에 1,2를 넣고 실행
        Debug.Log($"num = {num}");	
    }
	
    //===========콜백함수로 사용할 Add,Sub=============
    
    public int Add(int a, int b)	
    {
        Debug.Log($"a + b = {a + b}");
        return a + b;
    }

    public int Sub(int a, int b)	
    {
        Debug.Log($"a - b = {a - b}");
        return a - b;
    }

}

결과는 어떻게 될까요?
1+2를 num에 더하고, 1-2를 한번더 더해서, 3-1인 2가 나와야 할것같지만

처음에 실행된 Add 함수는 num에 더해지지 않았고❌,
마지막에 실행된 Sub 함수만 num에 담겨서 출력됐습니다.👌
(Add가 출력된것을 보면 Add 함수가 실행되지않은것도 아닙니다.)

이렇게 Func를 델리게이트 체인으로 만들면 마지막 함수의 결과만 반환합니다.

그래서 Func는 델리게이트 체인으로 사용하지 않고,
람다식으로 무명함수를 만들어 넣고 쓰고 싶을 때 쓰는 방법으로 사용하거나,
매개변수의 데이터 형식으로 이용합니다.

Func 사용법 1 : 무명함수를 넣어두고 사용

람다식을 이용한 Action,Func 콜백함수 등록

람다식을 사용하면
Action과 Func에 더욱 편하게 콜백함수를 등록할 수 있습니다.
간단한 함수의 경우 람다식을 만들어 바로 등록할수 있기 때문에 자주 사용됩니다.

Action에는 반환값이 없는 람다를 등록하여야 하고,

Func에는 반환값이 있는 람다를 넣어야합니다.

참고 : Func는 반환값이 반드시 필요한데, return이 안보입니다.

이유는 한줄로 끝나는 간단한 식은 {}를 제외할 수 있으며
반환값이 필요한 함수의 경우에는 return이 없어도
문장을 닫으면 반환값으로 인지
합니다. (형식유추 덕분입니다.)

람다식도 {}안에 식을 적을 수 있습니다. 이것을 "문 형식의 람다" 라고합니다.

전체 코드

using System;

public class Action대리자 : MonoBehaviour
{
    public Action myAction = () => Debug.Log("W키가 눌렸습니다.");

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            myAction();
        }
    }
}

public class Func대리자 : MonoBehaviour
{
    public Func<int, int, int> myFunc = (a, b) => a + b; 

    void Start()
    {
        Debug.Log(myFunc(1, 2));		// 3 출력
    }

}

Func 사용법 2 : 매개변수 타입으로 사용

함수 매개변수에는 (int num)같이 넣어야할 데이터 타입을 만들어줍니다.
그리고 우리는 여기에 정수를 넣겠죠? 0 이나 498 같은 숫자를 넣을겁니다.

그럼 이 매개변수 타입을 (Func func1)이렇게 지정한다면 우리는 무엇을 넣어야할까요?
여기엔 반환값이 있는 함수를 넣어주면 됩니다.

public Func<int, int, int> myFunc = (a, b) => a + b;

void Start()
{
    myMethod(myFunc);	// 인자로 같은 타입의 Func를 넣었음.
}

public void myMethod(Func<int,int,int> func)
{
    // 어떤 일
}

0개의 댓글