本文介绍了为什么不能将直接转换为代理的byref的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 限时删除!! 在正常情况下,F#函数可以通过调用 new DelegateType 转换为代理,并将该函数作为参数传递。但是当代理包含 byref 参数时,这是不可能的。例如代码: type ActionByRef<'a> ='by byref - >单位 let f(x:double byref)= x let x = ref 42.0 let d = new ActionByRef< _ ;(f) 不会编译,给出以下错误: 此函数值用于构造其签名包含一个byref参数的委托类型。您必须使用一个显式的lambda表达式,使用1个参数。 跟随错误,修改代码以使用 let d = new ActionByRef< _>(fun x - > f(& x)) / pre> 的作品。但我的问题是:为什么这是必要的?为什么F#不允许从命名函数转换为这个委托,但是从lambda转换是很好的? 当研究另一个问题。我意识到 byref 仅用于与其他.Net语言的兼容。解决方案 p>我认为问题是F $中的 byref<'T> 不是一个实际的类型 - 它看起来像一个类型(使语言更简单),但是它得到编译为标有 out 标志的参数。这意味着 byref<'T> 只能在编译器实际使用 out 标志的地方使用。 函数值的问题是可以构造函数eg通过部分应用: let foo(n:int)(b:byref< int>)= b< - n 当您通过 foo 一个委托构造函数的参数,它是部分应用程序(没有参数)的具体情况,但是部分应用程序实际上需要构造一个新的方法,然后将其赋给代理: type IntRefAction = byref< int> - >单位 let ac = IntRefAction(foo 5) 编译器可能是聪明,并使用 byref 参数(或 out 标志)生成新方法,然后通过引用传递给实际函数,但是一般来说,当您不使用 fun ...时,会有其他编译器生成的方法 - > ... 语法。处理这将增加复杂性,我认为这是一个相对罕见的情况,所以F#编译器不这样做,并要求你更加明确... Under normal circumstances, F# functions can be converted to delegates by calling new DelegateType and passing in the function as an argument. But when the delegate contains byref parameter, this is not possible directly. For example the code:type ActionByRef<'a> = delegate of 'a byref -> unitlet f (x:double byref) = x <- 6.0let x = ref 42.0let d = new ActionByRef<_>(f)won't compile, giving the following error: This function value is being used to construct a delegate type whose signature includes a byref argument. You must use an explicit lambda expression taking 1 arguments.Following the error, modifying the code to uselet d = new ActionByRef<_>(fun x -> f(&x))works. But my question is: why is this necessary? Why won't F# allow the conversion from named function to this delegate, but conversion from lambda is fine?I came upon this behavior when researching another question. I realize byref is meant only for compatibility with other .Net languages. 解决方案 I think the problem is that byref<'T> is not an actual type in F# - it looks like a type (to make the language simpler), but it gets compiled to a parameter marked with the out flag. This means that byref<'T> can be only used in a place where the compiler can actually use the out flag.The problem with function values is that you can construct function e.g. by partial application:let foo (n:int) (b:byref<int>) = b <- nWhen you pass foo as an argument to a delegate constructor, it is a specific case of partial application (with no arguments), but partial application actually needs to construct a new method and then give that to the delegate:type IntRefAction = delegate of byref<int> -> unitlet ac = IntRefAction(foo 5)The compiler could be clever and generate new method with byref parameter (or out flag) and then pass that by reference to the actual function, but in general, there will be other compiler-generated method when you don't use the fun ... -> ... syntax. Handling this would add complexity and I think that's a relatively rare case, so the F# compiler doesn't do that and asks you to be more explicit... 这篇关于为什么不能将直接转换为代理的byref的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 1403页,肝出来的..
09-07 15:10