我遇到了需要传递给Function对象的这个JQueryAnimationOptions类型。我通常会将lambda传递给回调,但它们似乎是不兼容的。我查找了所有我能在FunScript回购中找到的样本。却找不到任何解决办法。
它还说Function实际上是一个接口(用于什么?)当用作返回语句时,Error: Invalid use of interface type。
那么如何用这个Function类型传递回调参数呢?

守则:
[<FunScript.JS>]
module Main
open FunScript
open FunScript.TypeScript
let sayHelloFrom (name:string) =
Globals.window.alert("Hello, " + name)
let jQuery (selector:string) = Globals.jQuery.Invoke selector
let main() =
let options = createEmpty<JQueryAnimationOptions>()
options.duration <- 3000
options.complete <- (fun _ -> sayHelloFrom("F#"))
let properties = createEmpty<Object>()
properties.Item("opacity") <- 1
let mainContent = jQuery "#mainContent"
mainContent.animate(properties, options) |> ignore
mainContent.click(fun e -> sayHelloFrom("F#") :> obj)发布于 2015-01-07 09:39:39
在F#和C#之间传递lambda时,这或多或少地与您预期的一样。在F#中,可以对函数进行匆匆处理,而在C# (和JavaScript)中则不能。因此,当您需要将lambda从F#发送到C#时,您需要首先转换它。在F#中,这是通过像下面这样包装lambda来完成的:
open System.Linq
open System.Collections.Generic
let ar = [|1;2;3|]
let f = fun (x: int) (y: int) -> x + y
let acc = ar.Aggregate( System.Func<int,int,int>(f) )实际上,F#编译器可以推断大多数情况下的类型,所以您只需要编写:System.Func<_,_,_>(f)。此外,当将F# lambda传递给期待C# lambda的方法时,编译器会自动为您进行包装。然后,前面的示例如下:
let ar = [|1;2;3|]
let acc = ar.Aggregate( fun x y -> x + y )(当然,在这种情况下,最好使用惯用的Array.reduce。这只是一个人为的例子。)
这与使用FunScript与JS交互时的工作原理完全相同。您唯一需要注意的是如何将F# lambda转换为JS。为了允许运行,具有两个或多个参数(如fun x y -> x + y )的lambda变成:
function (x) {
return function (y) {
return x + y;
}
}这可能是一个问题,因为本机JS需要以下签名:function (x, y)。在这种情况下,您必须使用System.Func<_,_,_>()包装lambda,就像与C#交互时一样(请记住,如果将lambda传递给方法,就会自动完成)。
但是,只有一个参数的lambda不考虑任何问题:fun x -> x*x变成了function (x) { return x*x; }。在这种情况下,您不需要包装它们(无论如何,这样做也没什么坏处),只要在必要时使用unbox来安抚F#编译器就足够了。请注意,FunScript编译器在最终的JS代码中忽略了unbox,所以在运行时根本不会进行类型检查。
我希望这个解释是清楚的。如果不是,请添加评论,我会编辑答案。
发布于 2015-01-05 10:53:17
不管怎么说,我找到了解决办法,我不得不用unbox来表示:
options.complete <- unbox<Function> (fun _ -> sayHelloFrom("F#"))https://stackoverflow.com/questions/27776745
复制相似问题