2012-10-07 2 views
17

나는 몇 가지 방법이 암시 적 매개 변수를 복용 클래스를 정의하기 위해 노력하고있어 : 내가 다른 클래스에서이 클래스를 사용어떻게 클래스 수준에서 암시 적 매개 변수에 대한 기본값을 제공하는

object Greetings { 
    def say(name: String)(implicit greetings: String): String = greetings + " " +name 
} 

implicit val greetings = "hello"    //> greetings : java.lang.String = hello 
Greetings.say("loic")       //> res0: String = hello loic 
Greetings.say("loic")("hi")      //> res1: String = hi loic 

내 문제는 내 인사말 개체 외부에 암시적인 val을 정의 할 때만 작동한다는 것입니다. 스칼라 컬렉션 API와 같은 내 API를 더 쉽게 사용할 수 있도록 암시 적 매개 변수와 클래스에 기본값이있는 메서드를 제공하고 싶습니다.

그래서이 일을하고자하지만 (암시 적 값을 찾을 수 없음) 작동하지 않습니다 :

object Greetings { 
    implicit val greetings = "hello"  
    def say(name: String)(implicit greetings: String): String = greetings + " " +name 
} 

다음

Greetings.say("loic")       
Greetings.say("loic")("hi") 

을 내가 (implicit greetings: String = "hello")로 디폴트 값을 정의 할 수 있습니다 알고 있지만 나는 여러 가지 방법이 있다면 반복하지 않으려 고 클래스 수준에서하고 싶습니다.

CanBuildFromList 클래스 내에서 정의 된 것을 보았 기 때문에 뭔가 놓친 것 같습니다. 이처럼

class Greetings(implicit val greetings: String = "hello") { 
    def say(name: String): String = greetings + " " + name 
} 

내가 기본값을 가지고 있고 원하는 경우를 재정의 할 수 있습니다 :

답변

6

나는 해결 방법을 발견했습니다

new Greetings().say("loic")      //> res0: String = hello loic 

implicit val greetings = "hi"     //> greetings : java.lang.String = hi 
new Greetings().say("loic")      //> res1: String = hi loic 

new Greetings()("coucou").say("loic")   //> res2: String = coucou loic 

참고 : new Greetings()("coucou")이 있기 때문에,하지 new Greetings("coucou")을하고있다 문법의 낯설음은 here이라고 설명했다.

+0

그렇지 이상하다, 암시 만 일반 매개 변수에 두 번째 삽입되기 때문이다. 일반적으로 클래스는'class Greetings() (implicit val ...) '처럼 보일 것입니다. – thatsIch

24

String과 같은 일반적인 유형을 암시 적으로 사용하는 것은 좋지 않은 생각입니다. 주된 이유는 내재적 조회가 전적으로 해당 유형을 기반으로하므로 다른 누군가가 String 유형의 다른 암시 적 값을 정의한다면 어떨까요? 갈등으로 끝날 수도 있습니다. 따라서 자신 만의 고유 한 유형 (String을 둘러싼 간단한 래퍼)을 정의해야합니다.

암시 적 값을 찾을 때 컴파일러는 암시 적 값 유형의 컴패니언 객체 (있는 경우)를 (다른 위치에서) 찾습니다. 컴패니언 객체는 기본 암시 적 값을 넣는 자연스러운 장소이므로 (예 : 귀하의 경우와 같이) 얼마나 유용할지 쉽게 알 수 있습니다. 그러나 암시 적 값이 사용자가 소유하지 않은 유형 (예 : String) 인 경우에는 자체 래퍼 유형을 사용하는 동안 문제가없는 반면에 동반 개체를 작성할 수 없습니다. 여기

OK, 충분한 말씨는, 당신이 그것을 할 수있는 방법입니다 :

case class Greetings(value: String) { 
    override def toString = value 
} 
object Greetings { 
    // this implicit is just so that we don't have to manually wrap 
    // the string when explicitly passing a Greetings instance 
    implicit def stringToGreetings(value: String) = Greetings(value) 

    // default implicit Greetings value 
    implicit val greetings: Greetings ="hello" 

    def say(name: String)(implicit greetings: Greetings): String = greetings + " " +name 
} 
Greetings.say("loic")       
Greetings.say("loic")("hi") 
+0

알았어요. – Loic

관련 문제