編集: この質問の原因となったバグは修正されました。
Scala リファレンスで、私は読むことができます (p. 86):
単純変数 x = e への割り当ての解釈は、x の定義によって異なります。x が変更可能な変数を表す場合、代入によって x の現在の値が式 e の評価結果に変更されます。e の型は x の型に適合することが期待されます。x が何らかのテンプレートで定義されたパラメーターなしの関数であり、同じテンプレートにセッター関数 x_= がメンバーとして含まれている場合、代入 x = e はそのセッター関数の呼び出し x_=(e) として解釈されます。同様に、パラメーターなしの関数 x への代入 f .x = e は、呼び出し 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 の設計では、getter に型パラメーターがある場合でも、setter メソッドが呼び出されると便利です (ちなみに、setter に型パラメーターを追加します)。許可され、正常に動作します)。
だから私は3つの質問があります:
- 回避策はありますか?
- 現在の動作はバグと見なす必要がありますか?
- コンパイラが getter メソッドを強制して setter に構文糖衣を使用できるようにするのはなぜですか?
アップデート
これが私が本当にやろうとしていることです。かなり長いです。申し訳ありませんが、避けるつもりでしたが、省略した方が混乱を招くことに気付きました。
私は Scala で SWT を使用して GUI を設計しており、Dave Orme のXScalaWTを使用して非常に楽しんでいます。これにより、必要なコードの量が大幅に削減されます。Composite
°C を °F 度に変換する SWT の作成方法に関する彼のブログ投稿の例を次に示します。
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) })
)
)
ウィジェットを構築する各メソッドの引数は type(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 で <=> を定義でき、この優れた構文を使用できるため、人生はうまくいくでしょう。しかし残念なことに、ゲッターの型パラメーターはセッターを壊します。したがって、私の最初の質問: この単純な型パラメーターが、コンパイラーがセッターを呼び出すための構文糖衣を使用するかどうかに影響するのはなぜですか?
これで少しわかりやすくなったと思います。読んでくれてありがとう…</p>