2013-06-03 5 views
1

Мне нужен только один экземпляр класса, поэтому я должен использовать объект вместо класса. Мне также нужно установить некоторое начальное значение, выбранное клиентом, так что мне нужно конструктор для объекта, что-то вроде этого:Конструктор с параметром в Scala

object Object1(val initValue: Int){ 
    //..... 
} 

Я не могу использовать этот точный код в Scala. Как мне с этим бороться?

+0

Не следует, что вы _have_ используете объект, потому что вы только _need_ один экземпляр. Является ли это _requirement_, что существует только один экземпляр? –

+0

@ DanielC.Sobral, есть. –

+0

Как вы убедитесь, что создали его перед тем, как открыть его? – ziggystar

ответ

9

У вас есть несколько вариантов:

  1. Сделать это класс, есть клиент построить его, дать значение в параметре
    Pro: Консервированные неизменность
    Con: Имея только один экземпляр может быть трудно управлять

  2. Добавить переменную для параметра в объект, добавить сеттер.
    Pro: Вы еще одноплодная
    Con: Существует изменяемое состояние в настоящее время

  3. Реализовать multiton
    Pro: Дает (видимую) неизменность и одноплодный (за пары)
    Con: больше коды для реализации

Вы могли бы реализовать многотонные как это в Скале:

class Object1 private (val initValue: Int) { 
    // ... 
} 

object Object1 { 
    val insts = mutable.Map.empty[Int, Object1] 

    def apply(initV: Int) = 
    insts.getOrElseUpdate(initV, new Object1(initV)) 
} 

UPDATE Вы также могли бы превратить это в «синглтон с параметром»:

object Object1 { 
    var inst: Option[(Int, Object1)] = None 

    def apply(initV: Int) = inst match { 
    case Some((`initV`, i)) => i 
    case Some(_) => 
     sys.error("Object1 already instantiated with different param") 
    case None => 
     val i = new Object1(initV) 
     inst = Some((initV, i)) 
     i 
    } 
} 
+0

'apply()' в вашем «singleton with parameter» не является потокобезопасным. –

+0

А, да, действительно (кстати, и не относится к «мультитону»). Я думаю, что нет единственного решения для обеспечения безопасности этих потоков. Наиболее эффективным было бы создание, а затем и CAS, но это может быть несколько раз инициализировано. – gzm0

3

объект не будет создан, пока вы не ссылаться на него, так что вы могли бы сделать что-то вроде следующего:

object Test1 extends App { 
    var x = Console.readLine 
    println(Object1.initVal) 
} 

object Object1 { 
    val initVal:String = Test1.x 
} 
Смежные вопросы