2017-01-17 2 views
0

Я новичок в Scala и учась писать в нем персональный проект.Составляющие подклассы для достижения ограничения типа

У меня есть эта проблема и оглядываться не очень помогает. Так вот это -

abstract class Service{ 
def containsFeatures(x: Feature*) = ??? 
} 

object Service1 extends Service{.. 
def containsFeature(x: Feature*) 
} 

object Service2 extends Service{.. 
def containsFeature(x: Feature*) 
} 

Trait Feature 

case object A extends Feature 
case object B extends Feature 
case object C extends Feature 
case object D extends Feature 
case object E extends Feature 
case object F extends Feature 
case object G extends Feature 

Я хотел бы ограничить свой код таким образом, что Service1 определяет, какие функции возможны и которые являются ошибочными. Например: Service1 позволяет создавать объекты A, C, E, G и отображать ошибку при подаче других функций.

Можно ли программно ограничить это только нашим определением Service1 без изменения других классов?

Надеюсь, мой вопрос достаточно ясен.

Спасибо за любые предложения.

+0

Вы хотите сделать что-нибудь подобное? Service1.containsFeature (Список (A, C, E, G)) // OK Service1.containsFeature (List (B, D, F)) // throws Error –

+0

Вы имеете в виду, что он должен показывать ошибку во время компиляции, правильно? –

+0

Да, ошибка во время компиляции. – Adarsh

ответ

1

Если вы хотите, чтобы scalac отображал ошибку во время компиляции, когда задан неправильный Feature, и вы не можете изменить ничего, кроме Service1, тогда это невозможно. Компилятор принимает или отклоняет вызов на Service1.containsFeature на основе его интерфейса, но его интерфейс уже определен в Service, где говорится, что он примет любойFeature.

Если вы можете изменить информацию о другом коде, есть некоторые способы сделать это. Например, если вы можете все изменить:

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

abstract class Service[Allowed <: Feature] { 
    def containsFeatures(x: Allowed*): Unit 
} 

object Service1 extends Service[S1Feature] { 
    def containsFeatures(x: S1Feature*): Unit = println("ok") 
} 

object Service2 extends Service[S2Feature] { 
    def containsFeatures(x: S2Feature*): Unit = println("ok") 
} 

sealed trait Feature 
sealed trait S1Feature extends Feature 
sealed trait S2Feature extends Feature 

case object A extends S1Feature 
case object B extends S2Feature 
case object C extends S1Feature 
case object D extends S2Feature 
case object E extends S1Feature 
case object F extends S2Feature 
case object G extends S1Feature 

// Exiting paste mode, now interpreting. 

scala> Service1.containsFeatures(A,B,C) 
<console>:16: error: type mismatch; 
found : B.type 
required: S1Feature 
     Service1.containsFeatures(A,B,C) 
           ^

scala> Service1.containsFeatures(A,C,G) 
ok 
+0

Если бы мне пришлось менять подписи, определение подкласса функции для определения этих композиций и обновление подписи метода к соответствующему подклассу - это способ сделать это? – Adarsh

+0

@Adarsh ​​Я отредактировал свой ответ. –

+0

Спасибо за обновление. Интересно видеть эту схему использования. Тем не менее, это теперь помещает проверку компилятора, когда я пытаюсь передать объект типа Service1 методу, который принимает тип службы. Думаю, это компромисс в этом подходе? – Adarsh

Смежные вопросы