2016-08-25 123 views
0

Scala: can't write setter without getter?發現,你不能沒有消氣創建一個setter:爲什麼你不能在scala中創建一個沒有getter的setter?

分配到 解釋一個簡單的變量x = E取決於x的 定義。如果x表示 可變變量,則分配 將x的當前值改變爲 評估 表達式e的結果。 e的類型是 預期符合x的類型。 如果x爲在某些模板中定義的參數的函數 ,並且相同的 模板包含setter函數 X_ =作爲成員,則分配對象x = e爲解釋爲設定器的調用 X _ =(e)中功能。 類似地,賦值f.x = e到 無參數函數x被解釋爲調用f.x_ =(e )。將具有 函數應用於 左邊的賦值f(args)= e的'='運算符解釋爲f.update(args,e) ,即由f定義的更新函數的調用 。

所以這是一個設計決定,不允許setter沒有getter。但爲什麼? 難道只是難以實施,還是根本無法做到?

我確實有一個有效的用例,用它作爲一個(有點複雜的)setter,不使用這個語法糖會破壞項目中任何地方的相同語法。

+0

你能解釋一下情況嗎?爲什麼它有一個*問題*有一個getter? –

+0

@NathanielFord問題是它是一個API的一部分,它會混淆用戶認爲可以使用吸氣劑。情況:A類的一個對象有一個設置器來設置一定的值。 B類對象與A類的對象「連接」,可以使用具有相同名稱的getter來獲取該值。把它看作兩個設備之間的連線,其中一個設備只有一個輸出,這是另一個設備的輸入:(在A類中)out.value = 3.0和(在B類中)println(in.value ) –

+1

@ coolcat007:在這種情況下,您可能應該使用明確的setter方法而不是賦值。 – Bergi

回答

1

你可以試試這個從您的API排除訪問:

scala> class C { def c_=(i: Int) = println(i) ; private def c: Int = ??? } 
defined class C 

scala> val c = new C 
c: C = [email protected] 

scala> c.c = 42 
<console>:14: error: method c in class C cannot be accessed in C 
val $ires0 = c.c 
      ^
<console>:12: error: method c in class C cannot be accessed in C 
     c.c = 42 
     ^

scala> def f = { c.c = 42 ; 0 } 
<console>:12: error: method c in class C cannot be accessed in C 
     def f = { c.c = 42 ; 0 } 
       ^

在第一個錯誤,REPL正試圖通過使用訪問報告的價值。

成對訪問器和增變器的這種概念被稱爲通用訪問原則,因此訪問成員看起來像一個屬性。

表達式c.c必須進一步desugaring之前進行類型檢查。否則,變換(調用c.c_=)必須純粹是句法。

例如,提供擴展方法c_=的隱式轉換可以發揮作用。

+0

我對你答案的最後兩段有點困惑。你到底什麼意思? –

+0

只要'c.c'必須是自己的東西。如果你說'c.c ='只是'c.c_ =',那麼隱式轉換可能會添加'c_ ='mutator。擁有一個簡單的財產還有很長的路要走。 –

+0

考慮http://pastebin.com/yxsmumG3(是的,我知道,有些東西是鹽......)它可能不是一個「簡單」的屬性,但用法很清楚,可以看出getter的password '永遠不會被使用,而'password_ ='是這個例子核心部分的一半。我可以將'password_ ='重命名爲'setPassword'並明確地調用該方法,但是當我們使用Good Old Java時,我們又回來了。離開密碼獲取者會使使用該API的任何人感到困惑。 –

相關問題