2017-12-26 34 views
1

코드 블록을 고려하십시오.스칼라 함수가 함수 인수에 대문자 클래스 형식을 허용하는 이유는 무엇입니까?

class Evaluation { 
    def evaluate= { 
    println("Charlie...") 
    } 
} 
case class Dept(name:String) extends Evaluation 

def depEval(name:String,f:(String) => Evaluation) ={ 
    println(name) 
    f(name).evaluate 
} 
depEval("abc", Dept) 

왜 Dept는 Funtion1 형식으로 전달 될 수 있습니까? 스칼라는 인수를 해결하기 전에 유형을 확인하지 않습니다.

예상대로 위의 코드 스칼라 반면

def matchingCase(f: String => Evaluation)= { 
    println(f.toString()) 
    f match { 
    case Dept => println("function type matched") 
    } 
} 

matchingCase((x: String)=> Dept(x)) 

이 일치 오류를 제공 다른 조각을 고려하십시오.

답변

5

사례 클래스의 부록 개체는 FunctionX[T1, T2, <CaseClass>]까지 확장되므로 사례 클래스의 인스턴스를 생성하는 데 사용할 수 있습니다. 당신이 경우 클래스가있는 경우

따라서, 예를 들어,

case class Foo(i: Int, s: String) 

컴파일러는이이 같은 Foo의 인스턴스를 생성 할 수있는 동반자 객체

object Foo extends (Int, String) ⇒ Foo with Product2[Int, String] { 
    def apply(i: Int, s: String) = new Foo(i, s) 

    // and some other stuff such as equals, hashCode, copy 
} 

을 생성합니다

Foo(42, "Hello") 

대신

그래서
new Foo(42, "Hello") 

는 결론 : 이유를, 그 함수이기 때문에 함수이기 때문에 당신이 Dept 동반자 개체를 전달할 수있는 이유.

+0

동반자를 명시 적으로 정의하여이 동작을 깨기 쉽습니다. –

+0

그 문제는 https://github.com/scala/bug/issues/3664입니다. –

3

Dept은 "사례 클래스 유형"이 아니며 사례 클래스의 경우 object입니다. Function1 (인터페이스의 일부인 .apply 메서드가 있음)을 확장하여 함수가 예상되는 모든 곳에서 사용할 수 있습니다.

{ x => Dept(x) }Dept이 아니기 때문에 두 번째로 실패합니다.

+1

사실, Dept는'String => Dept'이고, η 확장이 없습니다. 두 번째 경우 함수 리터럴은'Dept '가 아닙니다. –

+0

@ som-snytt 아, 좋은 지적. 업데이트 중 ... – Dima

0

왜냐하면 매개 변수로 문자열을 취하고 Dept 객체를 의미하는 Dept 클래스의 인스턴스를 반환하는 것은 엉성한 행동을하기 때문에 (왜냐하면 매개 변수로주는 것만 큼 Dept) new 또는 다음 코드가 유효도 표정) 매개 변수로서 기능을 적용

val c: Dept.type = Dept 

val dep = c("Name1") 

dep 

RES1 : 부서 = 부서 (이름 1)

dep.evaluate 

찰리 ... RES2 : 단위 = ()