我目前正在使用F#中的Eto.Forms。我遇到的一个小麻烦是,当您在外部文件(XAML或JSON)中定义GUI对象(表单,面板,按钮等)并声明事件处理程序时,这些事件处理程序必须具有特定类型:
member public this.OnFirstButtonClicked (sender:Object, e:EventArgs) ->
MessageBox.Show(this, "First button was clicked")
|> ignore
member public this.OnSecondButtonClicked (sender:Object, e:EventArgs) ->
MessageBox.Show(this, "Second button was clicked")
|> ignore
类型签名的重复让我烦恼。 (在这两个函数中实际上有很多重复,比如调用带有几乎不同参数的MessageBox,但这只是一个测试项目。在一个真实的项目中,我会做一些不同的事情。这两个按钮。)我不想每次都重复这些功能的类型签名。阅读this page at F Sharp For Fun and Profit后,我想我可以这样做:
type EventHandler = (Object * EventArgs) -> unit
member public this.OnFirstButtonClicked : EventHandler ->
MessageBox.Show(this, "First button was clicked")
|> ignore
member public this.OnSecondButtonClicked : EventHandler ->
MessageBox.Show(this, "Second button was clicked")
|> ignore
然而,当我尝试这个时,我发现在成员函数上,语法实际上意味着"这个函数返回一个EventHandler函数"。我想说"这个成员函数 是一个EventHandler函数",我不知道该怎么做。
更新:自从撰写上述问题以来,我了解到我实际上并不需要指定事件处理函数的类型签名'参数。以下内容适用:
member public this.OnFirstButtonClicked (sender, e) ->
MessageBox.Show(this, "First button was clicked")
|> ignore
member public this.OnSecondButtonClicked (sender, e) ->
MessageBox.Show(this, "Second button was clicked")
|> ignore
然而,我真正的问题不是如何使这些事件处理程序工作?"我真正的问题是,"我已经学会了如何指定不是类的成员的函数的类型,但是我该怎么做呢? 是一个类的成员吗?"
答案 0 :(得分:1)
我将使用一些更简单的类型,但这里的想法是一样的。
考虑一个简单的类型:
type t() = member x.Test() = ();;
此处Test
明显具有unit -> unit
现在,我们尝试重写此内容以避免()
type t() = member x.Test : unit -> unit = ();;
但这会失败,因为右侧的值不正确。
这是一个解决方案:
type t() = member x.Test : unit -> unit = fun () -> () ;;
您可能尝试接近所需的一种解决方案是使用_
作为忽略的参数:
type t() = member x.Test _ : unit -> unit = () ;;
但这不起作用,因为我们现在是一个接受单个参数并返回一个函数的函数。
此时,我们真正想要的是Signature file,它将允许指定成员的类型签名。或者你可以尝试一个界面。
最后一种方法是在函数内部移动参数 - 然后它将成为
type t() = member x.Test : some signature = fun .....
答案 1 :(得分:1)
独立函数定义和方法定义之间的唯一区别是member
关键字和自标识符。除此之外,语法是相同的。
type AdditionFunction = int->int->int
let f:AdditionFunction = fun a b -> a + b
它实际上是一个值绑定,而不是一个函数绑定。该函数使用lambda表达式fun a b -> a + b
定义并绑定到标识符f。
要使用此类定义,您必须将事件处理程序定义为
type EventHandler = (Object * EventArgs) -> unit
member public this.OnFirstButtonClicked : EventHandler =
fun (_, _) ->
MessageBox.Show(this, "First button was clicked")
|> ignore
同样,对于独立功能,它的工作方式完全相同。