2017-11-10 57 views
2

我對SML(來自java世界)和我所瞭解的 結構與java類相似&的簽名是java接口。如何將getter/setter與sml結構相關

SML結構中的所有內容都是不可變的。有沒有可能有一個變量的值可以設置?

functor Make(M : sig 
       type data 
       val callback : _ 
      end) = struct 

    val cb = M.callback 

    fun simple nn = 
     cb(nn); 
     return nn 

    fun changeCallback cc = 
     cb = cc 
end 

上面的代碼編譯好沒有changeCallback函數。有沒有辦法改變變量cb的值並給出不同的回調函數?

回答

2

結構是最類似的Java類,它們不能實例化,只有靜態成員。像Java一樣,擁有全局可變狀態被認爲是一個壞主意。

您可以用

val cb : (argtype -> unit) ref = ref M.callback 

聲明添加可變的全局狀態,就像你可以在一個Java類public static Callback成員。但是這往往會導致問題。你也將不得不調整代碼位的其餘部分,讀取與!參考,並寫使用:=到:

functor Make(M : sig 
       type data 
       type arg 
       val callback : arg -> unit 
      end) = struct 

    val cb = ref M.callback 

    fun simple nn = ((!cb) nn; nn) 

    fun changeCallback cc = 
     cb := cc 
end 

另外請注意,沒有new運營商SML結構。函子可以用來創建新的結構,但是它們都必須在源代碼級別進行表示。例如,不可能在循環中創建可變數目的結構。

要模擬Java類,您需要使用記錄(可能包含… ref類型的成員)。

+0

所以現在我可以在changeCallback()中設置'state'?但後來我有一個函數引用不是一個int。那會是什麼語法(已經試過'_')? –

+0

我不認識'_'語法。我認爲你需要在仿函數的簽名參數中提供一個具體的類型。 –

1

要提供弗洛裏安的答案,SML確實有可變的變量,其中val foo = ref 0使得foo一個可變的INT,!foo是解除引用的值(實際INT),foo := 2改變其價值,fun incr r = (r := !r + 1 ; !r)是加1的可變參數的函數並返回更新的值。這是在不使用模塊系統(結構,簽名,仿函數)的情況下完成的。請注意,將;作爲SML中的二元運算符比將「命令式語言」看作「語句分隔符」更好。

SML不支持像Ocaml那樣的基於類的面向對象編程,並且坦率地說,使用模塊系統來模擬這一點會很可惜。你可能想看看Ocaml's object-oriented programming

如果你試圖完成一個特定的任務,那就是你的基於類的思維方式已經到位,那麼問一個更好的問題就是「你將如何在SML中建模X?」,考慮到它不是面向對象的,導向。