, Посмотрим, решит ли команда Scala это исправить.
тировать: ошибка, которая вызвала этот вопростеперь исправлено.
В справочнике Scala я могу прочитать (стр. 86):
Интерпретация присваивания простой переменной x = e зависит от определения x. Если x обозначает непостоянную переменную, то присваивание изменяет текущее значение x на результат вычисления выражения e. Ожидается, что тип e будет соответствовать типу x. Если x - это функция без параметров, определенная в некотором шаблоне, и тот же шаблон содержит функцию-установщик x_ = в качестве члена, тогда присваивание x = e интерпретируется как вызов x _ = (e) этой функции-установщика. Аналогично, присвоение f .x = e функции без параметров x интерпретируется как вызов f.x _ = (e).
Так, например, что-то вроде этого работает нормально:
class A {
private var _a = 0
def a = _a
def a_=(a: Int) = _a = a
}
Я могу тогда написать
val a = new A
a.a = 10
Но если я определю класс следующим образом, добавив параметр типа к методу a:
class A {
private var _a = 0
def a[T] = _a
def a_=(a: Int) = _a = a
}
тогда это больше не работает; Я получаюerror: reassignment to val
если я напишуa.a = 10
, Как ни странно, он все еще работает без параметра типа и списка неявных параметров, например.
Можно утверждать, что в этом примере параметр типа не очень полезен, но при разработке DSL было бы здорово вызвать метод setter, даже если у метода get есть параметры типа (и, между прочим, добавление параметров типа в setter). разрешено и работает нормально).
Итак, у меня есть три вопроса:
Есть ли обходной путь?Следует ли считать текущее поведение ошибкой?Почему компилятор принудительно применяет метод получения, позволяющий использовать синтаксический сахар для метода установки?ОБНОВИТЬ
Вот что я действительно пытаюсь сделать. Прошло довольно много времени, извините, я хотел этого избежать, но понял, что опускать его было более запутанно
Я проектирую GUI с помощью SWT в Scala и получаю огромное удовольствие, используя Дейва Орма.XScalaWT, что значительно уменьшает объем необходимого кода. Вот пример из его сообщения в блоге о том, как создать SWTComposite
который преобразует ° C в ° F градусов:
var fahrenheit: Text = null
var celsius: Text = null
composite(
_.setLayout(new GridLayout(2, true)),
label("Fahrenheit"),
label("Celsius"),
text(fahrenheit = _),
text(celsius = _),
button(
"Fahrenheit => Celsius",
{e : SelectionEvent => celcius.setText((5.0/9.0) * (fahrenheit - 32)) }
),
button(
"Celsius -> Fahrenheit",
{e : SelectionEvent => fahrenheit.setText((9.0/5.0) * celsius + 32) })
)
)
Аргумент для каждого из методов создания виджетов имеет тип(WidgetType => Any)*
с несколькими полезными неявными преобразованиями, которые, например, позволяют напрямую указывать строку для виджетов, которые имеютsetText()
метод. Все функции конструктора импортируются из одноэлементного объекта.
В конце я хотел бы иметь возможность написать что-то вроде этого:
val fieldEditable = new WritableValue // observable value
composite(
textField(
editable <=> fieldEditable,
editable = false
),
checkbox(
caption = "Editable",
selection <=> fieldEditable
)
)
Это связало бы редактируемое свойство текстового поля с выбором флажка через переменную WritableValue.
Первое: именованные аргументы здесь не применимы, поэтому строкаeditable = false
должен прийти откуда-то. Итак, наряду с методами конструирования виджетов в объекте-одиночке я мог бы написать концептуально:
def editable_=[T <: HasEditable](value: Boolean) = (subject: T) => subject.setEditable(value)
... но это работает, только если геттер также присутствует. Отлично: мне все равно нужен геттер для реализации привязки данных с помощью <=>. Что-то вроде этого:
def editable[T <: HasEditable] = new BindingMaker((widget: T) => SWTObservables.observeEditable(widget))
Если бы это сработало, жизнь была бы хорошей, потому что я могу определить <=> в BindingMaker и использовать этот приятный синтаксис. Но, увы, параметр типа на получателе нарушает установщик. Отсюда мой первоначальный вопрос: почему этот простой параметр типа влияет на то, решит ли компилятор продолжить использование синтаксического сахара для вызова метода установки?
Надеюсь, теперь это станет понятнее. Спасибо за чтение…