일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- play 강좌
- akka 강좌
- Hyperledger fabric gossip protocol
- 이더리움
- hyperledger fabric
- 스위프트
- 주키퍼
- CORDA
- 블록체인
- 안드로이드 웹뷰
- play2 강좌
- Golang
- 엔터프라이즈 블록체인
- Play2
- 파이썬 머신러닝
- 스칼라 동시성
- 하이브리드앱
- 플레이프레임워크
- 스칼라
- Actor
- 파이썬 강좌
- Akka
- Adapter 패턴
- 그라파나
- Play2 로 웹 개발
- 하이퍼레저 패브릭
- 스칼라 강좌
- 파이썬 데이터분석
- 파이썬 동시성
- 파이썬
- Today
- Total
HAMA 블로그
스칼라 강좌 (22) - apply 정리 본문
Apply
자바를 하다가 스칼라로 넘어오면 희안한거 많이 보는데 apply 라는 것도 분명히 마주치게 되는데 이게 여러군데에서 다른 의미로 사용되서 좀 헤깔리죠. 그래서 이 참에 정리 한번 하고 넘어 갑니다.
기본
해당 객체 뒤에 하나 이상의 값을 괄호{}로 둘러싸서 호출하면 그 객체의 apply() 메소드를 자동으로 호출해 줍니다. 스칼라에서는 apply 라는 메소드가 기본적으로 이 객체(타입) 저 객체(타입) 에 각자 정의되어 있습니다.함수타입에서 apply 하면 이렇게 작동하고 , 리스트에서 apply 하면 요렇게 작동하고 그렇습니다. 중구난방이라는 말 그래서 어느정도는 외워야합니다.
예를 보시죠
예1)
class applyTest {
def apply(n : Int): Unit = {
print ("hello world")
}
}
object test {
def main(arg : Array[String]): Unit ={
val at = new applyTest
at{10}
}
}
그냥 at{10} 로 호출하면 hello world 가 찍힙니다. 참고로 매개변수가 아예 없이는 안됩니다.
결국 {..} 사이에는 apply 의 인자가 들어가게 됩니다. 위에는 Int 형이 들어가네요.
예2)
class applyTest{
def apply( f : => Int): Unit ={
val n = f + 3
println("n = %d".format(n))
}
}
object test {
def main(arg : Array[String]): Unit ={
val t = new applyTest()
t{
println("apply test")
10
}
}
}
이게 참 골때리는 겁니다. 편의성을 높힌 Syntactic sugar 라고 하지만 여러언어를 쓰다보면 꽤 헥깔립니다.
먼저 applyTest 클래스에 apply 함수를 만들어 두었습니다. 이 apply 는 => Int 같은 람다식 (입력인자가 없고 리턴이 Int 형인) 함수타입을 인자로 받습니다. 여기까진 OK~
근데 10은 멀까요 -.-a
def apply( f : => Int)
여기에 f 에 대응되는 함수가
println("apply test")
return 10
란 야그죠.
결국 f + 3 은 10 + 3 과 같습니다.
예3) 함수 자체를 넘기기도 합니다.
class applyTest{
def apply( f : String => Unit): Unit ={
f("hello world")
}
}
object test {
def main(arg : Array[String]): Unit ={
val t = new applyTest()
t{
println
}
}
}
예4) 함수의 리턴값을 넘기기도 하고
object obj1{
def getWord: String = {
return "hello world"
}
}
class applyTest{
def apply( str : String): Unit ={
println(str)
}
}
object test {
def main(arg : Array[String]): Unit ={
val t = new applyTest()
t{
obj1.getWord
}
}
}
예4) 역시 이렇게 함수 자체를 넘길 수도 있습니다.
object obj1{
def getWord: String = {
return "hello world"
}
}
class applyTest{
def apply( block: => String): Unit ={
print(block)
}
}
object test {
def main(arg : Array[String]): Unit ={
val t = new applyTest()
t{
obj1.getWord
}
}
}
Array 에서의 apply
예 1) Array 에서의 값 가져오기
val a = new Array[String](2) // String 타입이 2개 담길수 있는 배열의 객체를 만들었네요.
a(0) 이렇게 하면 첫번째 값을 가져 올 수 있는데요. 객체에 바로 () 를 붙혔습니다. 어색하죠?
즉 여기선 a.apply(0) 이렇게 자동으로 변경 됩니다.
그리고 Array 에서의 apply 메소드의 역할은 해당 인덱스에 해당하는 값을 꺼내오는 겁니다.
예 2) Array 생성하기
val a = Array("hello", "world")
이렇게 만들 수 있습니다. new 가 생략되었는데 이게 가능한 이유는
암시적으로 apply() 라는 이름의 팩토리 메소드를 호출해서 객체를 만들어줍니다.
Array.apply("hello", "world") 이렇게 되는거죠 여기서는 ..
함수타입에서 사용
val f1 = (x: Int, y: Int) => x + y
f1(2,3) // f1.apply(2,3) 와 같다. 결과 : Int = 5
저렇게 호출하면 알아서 apply 해준다.
참고로 저 함수 리터럴의 타입은 <function2> 이며 스칼라에선 모든게 다 객체이다.
Set 에서의 apply
val fruit = Set("apple", "orange", "peach")
fruit("peach")
위에서 호출되는 apply 는 contains 와 동일하다.
Play2 에서 Action 호출에서의 사용
스칼라언어 기반 Play 프레임워크 웹개발에서는
def doSomething = Action{
Ok.apply(views.html.index("Hi there"))
}
이런 모양새로 이루어지는데 여기서 Action 이 무엇일까요?
위의 예는 다음과 같이 풀어지게 되는데요
def doSomething: Action[AnyContent] = Action.apply(
Ok.apply(views.html.index("Hi there"))
)
위의 apply 메소드의 정의는 apply(block: => Result) 이라 익명의 함수가 들어가게 됩니다.
이 말인 즉, Ok.apply 함수는 Result 를 반환하겠군요.
Action.apply 함수는 Result 를 사용한 후에 Action[AnyContent] 를 반환하구요.
'Scala' 카테고리의 다른 글
스칼라 강좌 (24) - 언더스코어 _ (0) | 2016.10.03 |
---|---|
스칼라 강좌 (23) - Null 과 친구들 (None, Nil, Unit) (0) | 2016.09.30 |
스칼라 강좌 (21) - Option 과 Either (0) | 2016.09.29 |
스칼라 강좌 (20) - 고차함수들 (zip,map,flatmap등) (0) | 2016.08.14 |
스칼라 강좌 (19) - implicit (0) | 2016.08.13 |