2016-07-30 4 views
6

클래스 생성기 (Avro 모델 용)를 만들고 싶습니다. 내가 생성하는 클래스의 필드가 언젠가 많은 다른 유형 중 하나 일 수 있기 때문에 문제가 있습니다. Int 또는 String 또는 무엇이든 될 수 있다고 가정 해 봅시다. 간단한 생각은 유형이 Any 인 해당 필드를 작성하고 런타임에 확인하는 것입니다.연합을 위해 Any를 사용하는 것이 좋습니다.

Any을 사용하면 스칼라 유형 시스템의 강력한 기능 중 일부가 삭제된다는 것이 문제입니다. 코드의 일부 버그는 컴파일시 잡히지 않을 것입니다. String 또는 IntAny으로 덮여 있다고 예상하는 함수에 List을 주면됩니다. 예를 들어

:

하자 나는이 내 수업에 대한 설명이 있습니다

class MyClass(myField: Any) 

나는 이런 식으로 뭔가를 만들려면 :이 설명에서

{"className" : "MyClass", "fields" : [ 
    { "fieldName" : "myField", "type" : ["String", "Int"]} 
]} 

을,이 클래스를 생성 :

class MyClass(myField: String or Int) 

Any의 사용을 중단해야합니까? Any을 사용하는 것이 일반적으로 스칼라 커뮤니티에서 좋은 생각으로 간주됩니까?

+0

다형성 클래스를 만들지 마십시오. 'class Foo [T]' –

+0

문제는 필드가 얼마나 많은 다른 타입을 가질 수 있는지 또는 다른 타입이 공통된 특징을 공유하는지에 대한 단서가 없다는 것입니다. – Moebius

+3

'Any'를 사용하는 것은 거의 좋은 생각이 아닙니다. 더 많은 문맥없이 조언을하기는 어렵다. –

답변

3

사용 일반적으로 스칼라 커뮤니티에서 좋은 아이디어로 간주되는 것은 무엇입니까?

아니요. Any은 유형 정보가 없음을 의미하므로 일반적으로 나쁜 습관으로 간주됩니다.

스칼라에서는 사용자가 유니온에서 가능한 많은 유형을 가지고 있다면 성가신 일이지만, 스칼라에서는 Either을 사용하여 유니온 유형을 나타낼 수 있습니다. 예 :

class MyClass(myField: Either[String, Int]) { 
    def doSomething = myField match { 
    case Left(myStringField) => ??? 
    case Right(myIntField) => ??? 
    } 
} 

또 다른 가능한 방법은 그 형태에 MyClass 제네릭 있도록하는 것입니다 :

class MyClass[A](myField: A) 

그러나이 A의 종류에 어떤 제약 조건을 설정하지 않습니다.

제약 조건을 배치하기 위해. 이 유형의 유한 집합 만들기, 당신은 임시 다형성을 사용할 수 있습니다 범위 암시 MyConstraint[A]가없는

trait MyConstraint[A] 
class MyClass[A: MyConstraint](myField: A) 

이제 new MyClass(myValue)는 컴파일되지 않습니다. 지금 당신은 당신이 암시 값

를 사용하여 허용 할 유형을 허용 목록에 추가 할 수 있습니다
implicit object IntConstraint extends MyConstraint[Int] 
implicit object StringConstraint extends MyConstraint[String] 

예 :

기술적 인 용어로
new MyClass(42) // ok, there's implicit evidence of MyConstraint[Int] 
new MyClass("foo") // ok, there's implicit evidence of MyConstraint[String] 
new MyClass(false) // won't compile, no implicit evidence of MyConstraint[Boolean] 

, MyConstraintMyClass의 생성자에서 유형 A를 수정하는 데 사용되는 유형의 클래스입니다 .

각 인스턴스에 대해 작업 집합을 정의해야하므로 형식 클래스를 더 자세히 특성 지정할 수 있습니다. 예 :

trait MyConstraint[A] { 
    def mandatoryOp: A 
} 

implicit object IntConstraint extends MyConstraint[Int] { 
    def mandatoryOp = 42 
} 

implicit object StringConstraint extends MyConstraint[String] { 
    def mandatoryOp = "foo" 
} 

class MyClass[A](myField: A)(implicit ev: MyConstraint[A]) { 
    def doSomething: A = ev.mandatoryOp 
} 

A: MyConstraint 유형 MyConstraint[A]의 암시 적 매개 변수를 필요로하는 단지 문법 설탕입니다 유의하시기 바랍니다. 마지막 예제에서 암시 적 매개 변수 ev을 범위에서 사용할 수 있도록 명시적인 구문을 선택했습니다.

+0

왜 ADT 패턴에 대한 언급이 없습니까? 가장 적절한 접근 방법 인 것처럼 보입니다. – Jubobs

관련 문제