개발 지식/CS 지식

πŸ‘¨‍πŸ’» 일급 객체(first-class object) λž€?

인파_ 2022. 12. 23. 09:33

first-class object

일급 객체 λž€?

보톡 μžλ°”μ˜ λžŒλ‹€ ν‘œν˜„μ‹(Lambda Expression)을 λ°°μš°λ‹€ 보면 '일급 객체' λΌλŠ” 단어λ₯Ό μ ‘ν•˜κ²Œ λ˜λŠ”λ°, λœ»μ„ 아무리 봐도 λŒ€μ²΄ 무얼 λ§ν•˜λŠ” 건지 와닿지 μ•Šμ„ 것이닀.

'일급' μ΄λž€ λœ»μ€ 일급 μ‹œλ―Ό 처럼 무슨 ν˜œνƒμ„ λ°›λŠ” λ‹€λŠ” 뜻이 μ•„λ‹ˆλΌ, μ‚¬μš©ν•  λ•Œ λ‹€λ₯Έ μš”μ†Œλ“€κ³Ό μ•„λ¬΄λŸ° 차별이 μ—†λ‹€λŠ” 것을 λœ»ν•œλ‹€.

그리고 보톡 일급 객체λ₯Ό μ•„λž˜ 3가지 쑰건을 μΆ©μ‘±ν•œ 객체λ₯Ό μΌμ»«λŠ”λ‹€.

  1. λͺ¨λ“  일급 κ°μ²΄λŠ” λ³€μˆ˜λ‚˜ 데이터에 담을 수 μžˆμ–΄μ•Ό ν•œλ‹€.
  2. λͺ¨λ“  일급 κ°μ²΄λŠ” ν•¨μˆ˜μ˜ νŒŒλΌλ―Έν„°λ‘œ 전달 ν•  수 μžˆμ–΄μ•Ό ν•œλ‹€.
  3. λͺ¨λ“  일급 κ°μ²΄λŠ” ν•¨μˆ˜μ˜ λ¦¬ν„΄κ°’μœΌλ‘œ μ‚¬μš© ν• μˆ˜ μžˆμ–΄μ•Ό ν•œλ‹€.

일급 κ°μ²΄λŠ” μ–΄λ– ν•œ νŠΉμ • 언어에 κ΅­ν•œλ˜λŠ” 문법 단어가 μ•„λ‹ˆλ‹€.

ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄λ‘ μ˜ κ°œλ…μœΌλ‘œμ„œ, μžλ°”λ‚˜ μžλ°”μŠ€ν¬λ¦½νŠΈ 외에 λ‹€μ–‘ν•œ μ–Έμ–΄κ°€ 이 일급 객체 κ°œλ…μ„ 가지고 μžˆλ‹€.

μš°λ¦¬κ°€ 많이 μ‚¬μš©ν•˜λŠ” 언어쀑 Javascript, Python이 일급객체 언어이고 c, pascal, c++κ°€ μ•„λ‹ˆλΌκ³  보면 λœλ‹€. (JavaλŠ” λžŒλ‹€λ‘œ 지원)
κ·Έλ ‡λ‹€κ³  이것이 뭐 μ’‹κ³  λ‚˜μ˜κ³  이런 κ°œλ…μ€ μ•„λ‹ˆλ‹€. λ‹€λ§Œ 일급 객체의 νŠΉμ„±μ€ 특히 ν•¨μˆ˜ν˜• μ–Έμ–΄λ“€μ—μ„œ μ€‘μš”ν•œ ν¬μΈνŠΈκ°€ λœλ‹€.

μžλ°”μ˜ λ©”μ†Œλ“œμ™€ μžλ°”μŠ€ν¬λ¦½νŠΈ ν•¨μˆ˜μ˜ 일급 객체

이번 μ‹œκ°„μ—λŠ” κ°€μž₯ 많이 μ‚¬μš©λ˜λŠ” Java와 JavaScript μ–Έμ–΄μ˜ 비ꡐλ₯Ό 톡해 이 '일급 객체' λΌλŠ” κ°œλ…μ„ μ•Œμ•„λ³Ό μ˜ˆμ •μ΄λ‹€.

μžλ°”μ˜ λ©”μ†Œλ“œλ„ 결ꡭ은 ν•¨μˆ˜μΈλ° μ™œ 이것을 일급 객체라고 λΆ€λ₯΄μ§€ μ•ŠλŠ” 것인지, μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ ν•¨μˆ˜λŠ” μ™œ 일급 객체인지 ν•˜λ‚˜ν•˜λ‚˜ μΆ©μ‘± 쑰건을 비ꡐ해 μ•Œμ•„λ³΄μž.

 

1. λ³€μˆ˜λ‚˜ 데이터에 담을 수 μžˆμ–΄μ•Ό ν•œλ‹€.

  • 생각해 보면 μžλ°”μ˜ λ©”μ†Œλ“œλŠ” λ³€μˆ˜μ— ν• λ‹Ήν•˜κ±°λ‚˜ 그럴순 μ—†λ‹€.
  • λ°˜λ©΄μ— μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν•¨μˆ˜ ν‘œν˜„μ‹μœΌλ‘œ 자유둭게 λŒ€μž…μ΄ κ°€λŠ₯ν•˜λ‹€.
public class Main {

    public static void hello(){
        System.out.println("Hello World");
    }

    public static void main(String[] args) {
		Object a = hello; // !! λ©”μ„œλ“œλ₯Ό λ³€μˆ˜μ— ν• λ‹Ή λΆˆκ°€λŠ₯
    }
}
const hello = function() {
	console.log("Hello World");
}

 

2. ν•¨μˆ˜μ˜ νŒŒλΌλ―Έν„°λ‘œ 전달 ν•  수 μžˆμ–΄μ•Ό ν•œλ‹€.

  • μ—­μ‹œ μžλ°”μ˜ λ©”μ†Œλ“œλ₯Ό λ©”μ†Œλ“œ μž…λ ₯κ°’μœΌλ‘œ λ³΄λ‚΄λŠ” ν–‰μœ„λŠ” λΆˆκ°€λŠ₯ν•˜λ‹€.
  • λ°˜λ©΄μ— μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 콜백 ν•¨μˆ˜ ν˜•νƒœλ‘œ 자유둭게 전달이 κ°€λŠ₯ν•˜λ‹€.
public class Main {

    public static void hello(){
        System.out.println("Hello World");
    }
    
    public static void print(Object func) {
    	func();
    }

    public static void main(String[] args) {
		print((Object) hello) // !! static λ©”μ„œλ“œλ₯Ό ν•¨μˆ˜ λ§€κ°œλ³€μˆ˜λ‘œ 전달 λΆˆκ°€λŠ₯
    }
}
const hello = function() {
	console.log("Hello World");
}

function print(func) {
	func();
}

print(hello);

 

3. ν•¨μˆ˜μ˜ λ¦¬ν„΄κ°’μœΌλ‘œ μ‚¬μš© ν• μˆ˜ μžˆμ–΄μ•Ό ν•œλ‹€.

  • μ—­μ‹œ μžλ°”μ˜ λ©”μ†Œλ“œμ˜ 리턴값을 λ©”μ†Œλ“œ 자체λ₯Ό λ°˜ν™˜ ν–‰νœ˜λŠ” λΆˆκ°€λŠ₯ν•˜λ‹€. 
  • λ°˜λ©΄μ— μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν΄λ‘œμ €(Closure) 기법을 톡해 ꡬ성할 수 μžˆλ‹€.
const hello = function() {
	console.log("Hello World");
    return function() {
    	console.log("Hello World 22");
    }
}

const hello2 = hello();
hello2();

μžλ°”μ˜ λžŒλ‹€ ν•¨μˆ˜μ˜ 일급 객체

μ΄λŸ¬ν•œ κ΄€μ μ—μ„œ μžλ°”μ˜ λžŒλ‹€μ‹ ν˜Ήμ€ 읡λͺ… ν΄λž˜μŠ€λŠ” λ³€μˆ˜λ‚˜ λ§€κ°œλ³€μˆ˜μ— ν• λ‹Ήν•  수 있고, λ¦¬ν„΄κ°’μœΌλ‘œλ„ μ‚¬μš©ν•  수있기 λ•Œλ¬Έμ— 일급 객체의 μš”κ±΄μ„ μΆ©μ‘±ν•œλ‹€.

 

1. λ³€μˆ˜λ‚˜ 데이터에 담을 수 μžˆμ–΄μ•Ό ν•œλ‹€.

import java.util.function.Consumer;

public class Main {
    public static void main(String[] args) {
        Consumer<String> c = (t) -> System.out.println(t); // λžŒλ‹€μ‹μ„ μΈν„°νŽ˜μ΄μŠ€ νƒ€μž… λ³€μˆ˜μ— ν• λ‹Ή
        c.accept("Hello World");
    }
}

 

2. ν•¨μˆ˜μ˜ νŒŒλΌλ―Έν„°λ‘œ 전달 ν•  수 μžˆμ–΄μ•Ό ν•œλ‹€.

import java.util.function.Consumer;

public class Main {
    // λ©”μ†Œλ“œ λ§€κ°œλ³€μˆ˜λ‘œ λžŒλ‹€ ν•¨μˆ˜λ₯Ό 전달
    public static void print(Consumer<String> c, String str) {
        c.accept(str);
    }

    public static void main(String[] args) {
        print((t) -> System.out.println(t) ,"Hello World");
    }
}

 

3. ν•¨μˆ˜μ˜ λ¦¬ν„΄κ°’μœΌλ‘œ μ‚¬μš© ν• μˆ˜ μžˆμ–΄μ•Ό ν•œλ‹€.

import java.util.function.Consumer;

public class Main {
    public static Consumer<String> hello() {
        // λžŒλ‹€ ν•¨μˆ˜ 자체λ₯Ό 리턴함
        return (t) -> {
            System.out.println(t);
        };
    }

    public static void main(String[] args) {
        Consumer<String> c = hello();
        c.accept("Hello World");
    }
}