2015-12-07 2 views
0

В Scala я хотел бы иметь что-то вроде этогоЗначения, чтобы указать использовать по умолчанию

TokenizerExample.scala

class TokenizerExample private (whateva : Any)(implicit val separator : Char = '.') { 

    def this(data2Tokenize : String)(implicit s : Char) { 
     this("", s) //call to base constructor 
    } 

    def this(data2Tokenize : Array[Char])(implicit s : Char) { { 
     this("", s) //call to base constructor 
    } 

} 

, что я хотел бы добиться того, чтобы позволить пользователю вызвать любого из два публичных конструктора либо предоставляют разделитель, либо не являются разделителями, но если они НЕ предоставляют разделитель, автоматически берут его в базовом конструкторе, мне было интересно, есть ли значение, которое я могу передать базовому конструктору, чтобы scala использовала значение по умолчанию на конструкторе частной базы.

, что я хотел бы избежать его, чтобы сделать следующий в каждом конструкторе

def this(_3rdConstructor : SytringBuilder)(implicit s : Char = '.') ... 

Я попытался это по-разному, причем значения являются неявно, с разделителем, как Option, но я не получить результат, который мне действительно нравится, особенно потому, что scala жалуется на наличие неявных значений в нескольких конструкторах (какой тип поражения имеет их цель). Есть ли способ добиться такого поведения красивым способом без

  • 1) заставляя пользователя предоставлять разделитель.
  • 2) перейти в «плохих-практик», передавая нулевые значения, а затем проверки их (особенно потому, что не позволило бы мой Сепаратор быть в конструкторе создается val.
  • 3) создание еще один язык только потому, что я не люблю маленькая мелочь об одном из них :).

ответ

1

Я бы настоятельно советовал вам использовать имплициты для этой цели. Правила разрешения довольно сложны, и это делает код чрезвычайно трудным для выполнения, потому что практически невозможно определить, какое значение получит конструктор без отладчика.

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

object Foo { 
    val defaultParam = ',' 
} 
class Foo { 
    import Foo.defaultParam 
    def this(data: String, param: Char = defaultParam) = ??? 
    def this(data: List[Char], param: Char = defaultParam) = ??? 
    // etc ... 
} 

Если вы настаиваете на использовании implicits, вы можете использовать подобный подход к выше: просто введите defaultParam определение implicit, отбросьте значения по умолчанию, заменив их неявными списками, а затем import Foo._ в области, где вы совершаете вызов. Но, действительно, не делайте этого: он не добавляет никакой ценности и имеет только недостатки в этом случае.

+0

Yup, как я и предполагал, в любом случае я оставлю вопрос без ответа, чтобы узнать, есть ли у кого-нибудь лучшее предложение, какое-либо хорошее предложение или обходное решение, и если этого не произойдет, я приму свой ответ. Спасибо @Dima – Ordiel

+0

Возможно, я мог бы придумать «обходной путь», если бы я лучше понял, что именно вы «работаете» :) Можете ли вы объяснить, как насчет этого решения, которое вам нужно улучшить? (я не очень-то сильно люблю принимать ответ, просто пытаясь помочь) – Dima

+0

хорошо, что я хочу «цепочку ответственности» за некоторые аргументы в моем конструкторе, чтобы я мог закончить с переменной «val» (в переменной java terms «public final», содержащей «разделитель»), я знаю, что могу сделать это, имея другое имя в параметре конструктора и затем назначая его разделителю «val» но это не очень умное использование памяти и переменных, а также я считаю, что лучше иметь собственные имена в моих аргументах (в этом случае разделитель), чтобы пользователь мог называть их «новым TockenizerExample (separator = '/ ', data = "bla") – Ordiel

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