首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在FunScript中传递“函数”类型?

如何在FunScript中传递“函数”类型?
EN

Stack Overflow用户
提问于 2015-01-05 09:37:59
回答 2查看 312关注 0票数 0

我遇到了需要传递给Function对象的这个JQueryAnimationOptions类型。我通常会将lambda传递给回调,但它们似乎是不兼容的。我查找了所有我能在FunScript回购中找到的样本。却找不到任何解决办法。

它还说Function实际上是一个接口(用于什么?)当用作返回语句时,Error: Invalid use of interface type

那么如何用这个Function类型传递回调参数呢?

守则:

代码语言:javascript
复制
[<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)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-07 09:39:39

在F#和C#之间传递lambda时,这或多或少地与您预期的一样。在F#中,可以对函数进行匆匆处理,而在C# (和JavaScript)中则不能。因此,当您需要将lambda从F#发送到C#时,您需要首先转换它。在F#中,这是通过像下面这样包装lambda来完成的:

代码语言:javascript
复制
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的方法时,编译器会自动为您进行包装。然后,前面的示例如下:

代码语言:javascript
复制
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变成:

代码语言:javascript
复制
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,所以在运行时根本不会进行类型检查。

我希望这个解释是清楚的。如果不是,请添加评论,我会编辑答案。

票数 2
EN

Stack Overflow用户

发布于 2015-01-05 10:53:17

不管怎么说,我找到了解决办法,我不得不用unbox来表示:

代码语言:javascript
复制
options.complete <- unbox<Function> (fun _ -> sayHelloFrom("F#"))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27776745

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档