2015-10-12 2 views
0

Я пытаюсь создать тип, который можно будет обновлять только один раз. В попрошайничестве объект имеет значение, и он будет генерировать исключение, если к нему обращаются. впоследствии пользователь может обновить объект, но другие обновления будут проигнорированы. это для того, чтобы иметь вид объекта состояния, который обновляет свое состояние один раз и во время потока, игнорирует фактический имп метода обновления, но я получаю ошибки компиляции варианта, контравариантный ... есть ли способ решить Это?Создание объекта Single updater

case class EmptyValueException(message: String = "empty value") extends RuntimeException(message) 

trait SingleUpdate[+T] { 
    def get: T 
} 

case object EmptyValue extends SingleUpdate[Nothing] { 
     def get: Nothing = throw EmptyValueException() 
} 

case class HasValue[+T](value: T) extends SingleUpdate[T] { 
    def get: T = value 
} 

object SingleUpdater { 
    def apply[T]() = new SingleUpdater[T]() 
} 

class SingleUpdater[+T] { 
     var single: SingleUpdate[T] = EmptyValue 
     def get = single.get 
     def update[T](value: T) = single = HasValue[T](value) 
    } 

ответ

1

Вот реализация вашего намерения, что компилирует счастливо, хотя она инвариантна в своем роде T. Кроме того, он игнорирует обновления после первого, и это то, что я понимаю, ваше намерение быть. Он делает это тихо, что вы, возможно, захотите изменить (например, выбросьте исключение, если пытаетесь обновить его снова).

case class EmptyValueException(message: String = "empty value") extends RuntimeException(message) 

trait SingleUpdate[T] { 
    def get: T = throw EmptyValueException() 
    def isSet = false 
} 

case class HasValue[T](value: T) extends SingleUpdate[T] { 
    override def get: T = value 
    override def isSet = true 
} 

object SingleUpdater { 
    def apply[T]() = new SingleUpdater[T]() 
} 

class SingleUpdater[T] { 
    var single: SingleUpdate[T] = new SingleUpdate[T] {} 
    def get = single.get 
    def update(value: T) = if (!single.isSet) single = HasValue[T](value) 
} 

Пример использования:

scala> val su = SingleUpdater[String] 
su: SingleUpdater[String] = [email protected] 

scala> su.get 
EmptyValueException: empty value 
    at SingleUpdate$class.get(<console>:10) 
    at SingleUpdater$$anon$1.get(<console>:28) 
    at SingleUpdater.get(<console>:29) 
    at .<init>(<console>:10) 
    at .<clinit>(<console>) 
    at .<init>(<console>:7) 
    at .<clinit>(<console>) 
    ... 

scala> su.update("Foo") 

scala> su.get 
res2: String = Foo 

scala> su.update("Bar") 

scala> su.get 
res4: String = Foo