Scala์ def์ val, ๊ทธ๋ฆฌ๊ณ ํจ์ ๋ฆฌํฐ๋ด
์ค์นผ๋ผ ์คํฐ๋ ์งํ ์ค ํ์ํ๋ค๊ณ ๋๊ปด def ์ val์ ๋ํ ์ด์ผ๊ธฐ๋ฅผ ๋๋ฆ ์ ๋ฆฌํด๋ดค๋ค. def์ val์ ๋ํ ์ฐจ์ด์ ์ ์ค์นผ๋ผ๊ฐ function literal ํน์ function value๋ฅผ ์ด๋ป๊ฒ ๋ค๋ฃจ๋์ง ์ดํด๋ณด๋ฉด ๋ณด๋ค ์ฝ๊ฒ ์ดํดํ ์ ์๋ค.
Function Literal๊ณผ Function Value
ํจ์ ๋ฆฌํฐ๋ด(function literal)์ (a:Int)=> a+1 ๊ณผ ๊ฐ์ ํํ๋ก ํํ๋๋๋ฐ, ์ค์นผ๋ผ์์ ํจ์ ๋ฆฌํฐ๋ด์ ์ค์ ๋ก๋ FunctionN์ด๋ผ๋ ํด๋์ค์ด๋ค. ์ฌ๊ธฐ์ N์ ์ธ์ ๊ฐ์๋ฅผ ๋ํ๋ธ๋ค. ์๋ฅผ ๋ค์ด, ์ธ์๊ฐ ๋ ๊ฐ์ธ ํจ์ ๋ฆฌํฐ๋ด์ ๋ํ๋ด๋ ํด๋์ค๋ Function2์ด๋ค. ์ค์นผ๋ผ์์ ํจ์ ๋ฆฌํฐ๋ด์ ํด๋์ค๋ก ์ทจ๊ธํ๋ค๋ ์ฌ์ค์ ์์ฃผ ์ค์ํ๋ค.
์ฐธ๊ณ ๋ก FunctionN ํด๋์ค๋ def๋ก ๋ง๋ ์ผ๋ฐ์ ์ธ ํจ์๊ฐ ์๋, ํจ์ ๋ฆฌํฐ๋ด์ ๋ํ๋ด๋ ํ์ ์์ ์ฃผ์ํ๋ค. ํ์ธ์ ์ํด def๋ก ์ผ๋ฐ์ ์ธ ํจ์๋ฅผ ํ๋ ์ ์ํด ๋ณด๊ฒ ๋ค.
scala> def sum(a:Int, b:Int) = a + b sum: (a: Int, b: Int)Int
sum์ ํ์ ์ ๋ณด๋ฉด (a: Int, b: Int)Int ์ธ๋ฐ, ๋์ค์ ํ์ธํด ๋ณด๊ฒ ์ง๋ง ์ด๋ ํจ์ ๋ฆฌํฐ๋ด์ ํด๋นํ๋ ํ์ ์ด ์๋๋ค. ํจ์ ๋ฆฌํฐ๋ด์ด๋ผ๋ฉด Function2 ํน์ (Int, Int):Int ํ์ ์ด๋ผ๊ณ ์ถ๋ ฅ๋์ด์ผ ํ๋ค.
def๋ก ์ ์ํ ํจ์๋ฅผ ํจ์ ๋ฆฌํฐ๋ด๋ก ์ ์ํ ํจ์๋ก ๋ง๋๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด partially applied function์ ์ด์ฉํ๋ฉด ๋๋ค. ์ถ๋ ฅ ๊ฒฐ๊ณผ์ ๋ณด์ด๋ function2๋ Function2์ ์ธ์คํด์ค๋ผ๋ ์๋ฏธ์ธ๋ฐ, function2์ ๊ฐ์ด ํจ์ ๋ฆฌํฐ๋ด์ ์ด์ฉํด ๋ง๋ ์ธ์คํด์ค๋ฅผ function value๋ผ๊ณ ํ๋ค.
scala> sum _ res1: (Int, Int) => Int = <function2>
์ ์์์๋ ๋ชจ๋ ์ธ์๋ฅผ ๊ทธ๋๋ก ํ์ฉํ์ง๋ง, ๋ค์๊ณผ ๊ฐ์ด ์ธ์ 1๊ฐ๋ฅผ ๊ณ ์ ํ๋ฉด Function2 ๋์ Function1์ ์ธ์คํด์ค๊ฐ, ๋ค์ ๋งํด function value๊ฐ ๋ฐํ๋จ์ ํ์ธํ ์ ์๋ค.
scala> sum( 1, _:Int) res2: Int => Int = <function1>
์ด์ ๋ณธ๋ก ์ผ๋ก ๋ค์ด๊ฐ function value์ ํจ์๋ฅผ fist class๋ก ๋ค๋ฃจ๋๊ฒ ์ด๋ค ๊ด๊ณ์ธ์ง ์ดํด๋ณด๋ ค๊ณ ํ๋ค.
partially applied function์ ๊ฒฐ๊ณผ๋ funciton value์์ ํ์ธํ๋ค. ์ด๊ฒ ๋ญ ์ด๋ป๋ค๋ ๋ง์ผ๊น? Java ๋ฑ์ ๊ฐ์ฒด ์งํฅ ์ธ์ด๋ฅผ ์ฌ์ฉํ ๊ฒฝํ์ด ์๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํน์ ๋ณ์์ ๊ฐ์ฒด์ ์ธ์คํด์ค๋ฅผ ๋ณด๊ดํ๋ ๊ฒ์ด ์์ฃผ ์์ฐ์ค๋ฝ๋ค.
scala> val person = new Person("์์์ฌ์ด๋ค", 35)
๋ง์ฐฌ๊ฐ์ง๋ก ํจ์๋ฅผ ๋ณ์์ ๋ด๊ฑฐ๋, ์ธ์๋ก ์ ๋ฌํ๊ฑฐ๋, ํจ์์ ๋ฆฌํด ๊ฐ์ผ๋ก ๋ฐํํ๊ธฐ ์ํด, FunctionN ๊ฐ์ฒด์ ์ธ์คํด์ค๋ฅผ ํน์ ๋ณ์์ ๋ณด๊ดํ๋ ๊ฒ ๋ํ ๊ฐ๋ฅํ๋ค.
scala> val sum = (a:Int, b:Int) => a + b sum: (Int, Int) => Int = <function2>
๊ฒฐ๊ตญ ์ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
scala> val sum = new Function2[Int, Int, Int] { | def apply(a:Int, b:Int):Int = { | a + b | } | } sum: java.lang.Object with (Int, Int) => Int = <function2> scala> sum(1,2) res0: Int = 3
๋ค์ ๋งํ๋ฉด ์ค์นผ๋ผ์์๋ function literal์ ํด๋์ค๋ก ์ ์ํ์ฌ ํจ์๋ฅผ first class๋ก ๋ง๋ค์๊ธฐ ๋๋ฌธ์, ์ผ๋ฐ์ ์ธ ๊ฐ์ฒด์ธ ํจ์(์ ํํ๋ function value)๋ ๋ค๋ฅธ ๊ฐ์ฒด์ ๋ง์ฐฌ๊ฐ์ง๋ก ์์ ๋ก์ด ์ ๋ฌ์ด ๊ฐ๋ฅํ๋ค.
์ง๊ธ๊น์ง ์ค๋ช ํ ๋ด์ฉ์ ์ดํดํ๋ค๋ฉด, stackoverflow ๋ฑ์ ์ฌ๋ผ์จ val์ def์ ๋ํ ์ง๋ฌธ๋ค์ ํ์ธํด๋ณด๋ฉด ์กฐ๊ธ ๋ ์ดํด๊ฐ ์ ๋ ์ง๋ ๋ชจ๋ฅด๊ฒ ๋ค. ํ๊ตญ ์ค์นผ๋ผ ์ฌ์ฉ์ ๋ชจ์ ๋ฉ์ผ๋ง ๋ฆฌ์คํธ์์ def๊ณผ ๊ด๋ จ๋ ๋ด์ฉ์ ์ด์ผ๊ธฐ ํ๋ค๊ฐ ๋ค์๊ณผ ๊ฐ์ ๋งํฌ๊ฐ ๋ฑ์ฅํ๋๋ฐ, ์๊ฐ์ด ๋๋ฉด ํ์ธํด๋ณด๊ธธ ๋ฐ๋๋ค. ๊ทผ๋ณธ์ ์ผ๋ก๋ ๊ฐ์ ๋ด์ฉ์ด์ง๋ง ์กฐ๊ธ ๋ค๋ฅธ ์ง๋ฌธ์ ํ๊ณ ์๋ค.
http://stackoverflow.com/questions/3646756/scala-def-versus-val
def ํน์ val์ ์ค๋ฒ๋ผ์ด๋ ํ ๋ ์ ์ ์ฌํญ
๊ฐ๋จํ๊ฒ ์ ๋ฆฌํ๋ฉด def๋ฅผ val๋ก overrideํ์ง๋ ๋ชปํ์ง๋ง, val์ def๋ก overrideํ๋ ๊ฒ์ ๊ฐ๋ฅํ๋ค.
scala> class A { val a=0 }; class B extends A { override def a=1 } // ์คํจ <console>:4: error: error overriding value a in class A of type Int; method a is not stable class A { val a=0 }; class B extends A { override def a=1 } ^ scala> class A { def a=0 }; class B extends A { override val a=1 } // ์ฑ๊ณต defined class A defined class B
A = new B ์ ๊ฐ์ด ์ ์ธํ์ฌ ์ฌ์ฉํ๋ค๊ณ ํ๋ฉด A.a๋ statelessํ๋ค๊ณ ๊ฐ์ ํ๊ณ ์ฌ์ฉ๋ ๊ฒ์ด๋ค. ํ์ง๋ง ์ค์ ๊ตฌํ์ด def์ด๋ฉด ํด๋น ๋ฉค๋ฒ๊ฐ ์ํ๊ฐ ์๋ค๋ ๊ฒ์ ๋ณด์ฅํ๊ธฐ ํ๋ค๋ค. ๋๋ฌธ์ Scala์์๋ def๋ฅผ val๋ก override ํ๋ ๊ฒ๋ง์ ํ์ฉํ๋ค.









