Scala에서 암시 적 인수가 여러 개있는 함수 정의


94

암시 적 인수가 여러 개인 함수를 어떻게 정의 할 수 있습니까?

def myfun(arg:String)(implicit p1: String)(implicit p2:Int)={} // doesn't work

2
질문 텍스트에서 기능에 대해 묻습니다. 코드 스 니펫에는 메소드가 있습니다. 기능이나 방법에 대해 질문하고 있습니까?
Jörg W Mittag

답변:


190

모두 하나의 매개 변수 목록에 있어야하며이 목록은 마지막 목록이어야합니다.

def myfun(arg:String)(implicit p1: String, p2:Int)={} 

1
클래스라면 구문은 class MyClass () (implicit p1 : String, implicit p2 : Int) {}
skjagini

2

실제로 OP에 필요한 것을 정확히 수행하는 방법이 있습니다. 약간 복잡하지만 작동합니다.

class MyFunPart2(arg: String, /*Not implicit!*/ p1: String) {
  def apply(implicit p2: Int) = {
    println(arg+p1+p2)
    /* otherwise your actual code */
  }
}

def myFun(arg: String)(implicit p1: String): MyFunPart2= {
  new MyFunPart2(arg, p1)
}

implicit val iString= " world! "
implicit val iInt= 2019

myFun("Hello").apply
myFun("Hello")(" my friend! ").apply
myFun("Hello")(" my friend! ")(2020)

//  Output is:
//      Hello world! 2019
//      Hello my friend! 2019
//      Hello my friend! 2020

Scala 3 (일명 "Dotty"는 컴파일러의 이름 임)에서는 보조 MyFunPart2 객체 를 반환하는 대신 암시 적 인수를 사용하여 함수 값을 직접 반환 할 수 있습니다. 이것은 Scala 3가 "암시 적 함수"를 지원하기 때문입니다 (즉, "매개 변수 암시성"는 이제 함수 유형의 일부입니다). 다중 암시 적 매개 변수 목록은 구현하기가 너무 쉬워 져서 언어가 직접 지원할 수 있지만 확실하지는 않습니다.


1

비슷한 효과를 얻을 수있는 또 다른 방법 (IMO가 더 간단하고 유연함)이 있습니다.

// Note the implicit is now a Tuple2
def myFun(arg: String)(implicit p: (String, Int) ): Unit = {
  println(arg + p._1 + p._2)
  /*otherwise your actual code*/
}

// These implicit conversion are able to produce the basic implicit (String,Int) Tuples
implicit def idis(implicit is: String, ii: Int): (String,Int)= (is,ii)
implicit def idi(s: String)(implicit ii: Int): (String,Int)= (s,ii)

// The basic implicit values for both underlying parameters
implicit val iString = " world! "
implicit val iInt = 2019

myFun("Hello")
myFun("Hello")(" my friend! ")
myFun("Hello")(" my friend! ",2020)

// Output is:
//     Hello world! 2019
//     Hello my friend! 2019
//     Hello my friend! 2020

// If we add the following implicit, 
implicit def ids(i: Int)(implicit is: String)= (is,i)

// we can even do
myFun("Hello")(2020)

// , and output is:
//     Hello world! 2020

튜플을 매개 변수의 기본 표현으로 사용하는 것은 암시 적 변환이 다른 사용을 방해 할 수 있기 때문에 좋은 생각이 아닙니다. 실제로 표준 유형 (라이브러리 유형 포함)으로의 암시 적 변환은 일반적으로 사소하지 않은 응용 프로그램에서 문제를 일으 킵니다. 해결책은 튜플 대신 매개 변수를 보유하는 전용 케이스 클래스를 만드는 것입니다. 중요한 장점은 _1 및 _2보다 훨씬 더 의미있는 이름을 지정할 수 있다는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.