'2019/11'에 해당되는 글 1건

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

play framework로 이런저런 작업과 스칼라 관련 모임에서 코드를  보는 와중에 

 

implicit 키워드가 눈에 자주 보인다. 

 

나중에 혼란스러워 하지말고 미리 정리.

 

- implicit parameter 

(참고 : https://docs.scala-lang.org/ko/tutorials/tour/implicit-parameters.html.html

먼저 메인 클래스를 선언한다.

object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("hello, world!")
  }

  def testFunction(name : String)(implicit liveObject : LiveObject) : Unit = {
    println("I am " + name)
    liveObject.introduce();
  }
}

 

간단하다, Hello, world 문자열하나만 보여준다. testFunction 은 implicit 파라미터로 LiveObject 를 사용중이다.

testFunction 은 지금 당장은 사용하지 않으니 "이런게 있구나" 수준으로 넘어가자.

 

trait의 내용은 아래와 같다. 

trait LiveObject {
  def introduce() = {
    println("I am LiveObject")
  }
}

이제 LiveObject 를 믹스인한 클래스 두 개를 생성한다.

class Animal extends LiveObject {
  override def introduce(): Unit = {
    println("I am Animal")
  }
}

class Human extends LiveObject {
  override def introduce(): Unit = {
    println("I am Human")
  }
}

 

간단하다 introduce 를 재정의 해서 문자열 하나만 다르게 재정의 했다.

 

준비작업은 모두 끝났다. 이제 main 함수 내에서 testFunction 을 호출을... 했는데? 어라? 에러가 있네?

main 함수 안에서 testFunction 호출한 모습

에러 내용을 자세히 보면 

implicit 파라미터 없음.

직접 넣어줄 수는 있다.. 근데 이건 '암시적' 아닌 것 같아 다른 방법을 찾아본다.

 

바로 위에 Animal 변수를 하나 추가해준다.. 이러면 돌아가겠지.

 


object HelloWorld {

  def main(args: Array[String]): Unit = {
    println("hello, world!")
    val animal = new Animal
    testFunction("thomas")
  }

  def testFunction(name : String)(implicit liveObject : LiveObject) : Unit = {
    println("I am " + name)
    liveObject.introduce()
  }
}

 

여전히 에러가 난다. 

 

여전히 변수를 못찾음.

암시적 파라미터 관련 스칼라 문서를 다시 읽어보면... 

 

스칼라 컴파일러는 implicit 파라미터를 만났을 때, 실제 파라미터에 할당할 변수를 검색하는데 규칙은 다음과 같다. 

1. 메서드가 호출되었을 때, prefix 없이 접근할 수 있는 변수 (당연히 변수들은 implicit 키워드가 붙어야 함.)

2. implicit 키워드가 붙은 암시적 파라미터와 관련된 모든 멤버 

 

2번은 조금 어려우니 일단 1번부터, 암시적 파라미터를 설정하려면 implicit 을 붙여야 한다. 변수를 implicit 으로 변경해서 다시.


object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("hello, world!")
    implicit val animal = new Animal
    testFunction("thomas")
  }

  def testFunction(name : String)(implicit liveObject : LiveObject) : Unit = {
    println("I am " + name)
    liveObject.introduce()
  }
}

이번엔 실행이 제대로 된다.


  hello, world!
  I am thomas
  I am Animal
  Process finished with exit code 0

암시적 변수 / 함수를 선언하려면 implicit 키워드를 사용하여 선언해야 정상적으로 인식하는듯

 

그러면 이번에 같은 type 을 두 개 넣으면 어떻게 될까? 


def main(args: Array[String]): Unit = {
    println("hello, world!")
    implicit val animal = new Animal
    implicit val human = new Human
    testFunction("thomas")
}

실행 해보니 아래와 같은 Exception 이 발생한다. 

 

같은 implicit 변수가 두개 선언되었을 때 Exception

머릿속에 어느정도 그림이 그려진다. 

 

implicit 파라미터는 "함수가 호출 된 타이밍" 에 prefix 없이 접근 가능한 변수 중 "가장 가까운 변수 " 가 할당되다 라고 이해하면 빠를듯.

 

다음번엔 implicit function 을 좀 더 봐야겠다.

 

2019년 11월 18일 추가 

 

변수의 scope 가 다를경우 같은 타입의 implicit 의 선언이 가능하다. 이 경우에 가장 최근에 선언된 implicit 변수가 사용된다.

 


object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("hello, world!")
    implicit val human = new Human
    overlapfunction()
  }

  def overlapfunction()(implicit liveObject : LiveObject) : Unit = {
    implicit val animal = new Animal
    testFunction("thomas")
  }

  def testFunction(name : String)(implicit liveObject : LiveObject) : Unit = {
    println("I am " + name)
    liveObject.introduce()
  }
}

위 코드를 실행하면 아래와 같은 결과가 나온다.

 

 


hello, world!
I am thomas
I am Animal
블로그 이미지

캡틴토마스

그저 걷고 있는거지...

,