F#等同于C#的“输出” [英] The F# equivalent of C#'s 'out'

查看:110
本文介绍了F#等同于C#的“输出”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将C#库重写为F#,我需要翻译以下代码

I am rewriting a C# library to F# and I need to translate the following code

bool success;
instance.GetValue(0x10, out success);

相当于 out 关键字的含义在F#中?

what is the equivalent of the out keyword in F#?

推荐答案

wasatz的答案和Max Malook的答案都不完整。带有 out 参数的方法有三种调用方法。第二种和第三种方法也可以使用 ref 参数。

Neither wasatz's answer nor Max Malook's is complete. There are three ways of calling methods with out parameters. The second and third ways also work with ref parameters.

对于示例,假定以下类型:

For the examples, assume the following type:

open System.Runtime.InteropServices //for OutAttribute
type SomeType() =
    member this.GetValue (key, [<Out>] success : bool byref) =
        if key = 10 then
            success <- true
            "Ten"
        else
            success <- false
            null

还假定我们有一个该类型的实例:

Assume also that we have an instance of that type:

let o = SomeType()



选项1



您可以让F#编译器通过将其与返回值绑定来处理out参数:

Option 1

You can let the F# compiler handle the out parameter by tupling it with the return value:

let result1, success1 = o.GetValue 10
let result2, success2 = o.GetValue 11

在F#交互式收益中运行以上行

Running the above lines in F# interactive yields

val success1 : bool = true
val result1 : string = "Ten"
val success2 : bool = false
val result2 : string = null



选项2



您可以使用可变值,并将其地址传递给& 运算符:

let mutable success3 = false
let result3 = o.GetValue (10, &success3)
let mutable success4 = false
let result4 = o.GetValue (11, &success4)

在F#交互中,结果为

val mutable success3 : bool = true
val result3 : string = "Ten"
val mutable success4 : bool = false
val result4 : string = null

当您委派给另一个方法时,此选项是最佳选择,因为您可以将调用方法的out参数直接传递给被调用方法。例如,如果您要在 IDictionary< _,_> 周围实​​现包装,则可以将 TryGetValue 方法编码为

This option is best when you are delegating to another method, since you can pass the calling method's out parameter directly to the called method. For example, if you are implementing a wrapper around IDictionary<_,_>, you can code the TryGetValue method as

//...
interface IDictionary<'TKey, 'TValue> with
    member this.TryGetValue (key, value) = inner.TryGetValue (key, &value)
    //...



选项3



您可以使用参考单元格:

Option 3

You can use a reference cell:

let success5 = ref false
let result5 = o.GetValue (10, success5)
let success6 = ref false
let result6 = o.GetValue (11, success6)

输出:

val success5 : bool ref = {contents = true;}
val result5 : string = "Ten"
val success6 : bool ref = {contents = false;}
val result6 : string = null



警告!



请注意不要像在C#中使用in / out参数那样使用 ref 关键字。例如,以下内容不会产生预期的结果:

Warning!

Be careful not to use the ref keyword as you would in C# for an in/out parameter. For example, the following does not yield the desired result:

let success7 = false
let result7 = o.GetValue (10, ref success7)

输出:

val success7 : bool = false
val result7 : string = "Ten"

为什么 success7 保留值 false ?因为 success7 是一个不可变变量。

Why does success7 hold the value false? Because success7 is an immutable variable.

在C#中, ref 请注意以下事实:您正在传递对变量的引用作为 ref 参数的参数。它只是作为保证,调用方的程序员知道该变量可以被调用的方法修改。但是,在F#中, ref 创建一个新的引用单元格,其中包含以下表达式的值的副本。

In C#, ref calls attention to the fact that you are passing a reference to a variable as the argument for a ref parameter. It simply serves as insurance that the programmer of the caller is aware that the variable may be modified by the called method. In F# however, ref creates a new reference cell holding a copy of the value of the following expression.

在这种情况下,我们将创建一个引用单元格,该引用单元格保存从 success7 变量复制的值,但不将该新引用单元格分配给任何变量。然后,我们将该引用单元格传递给GetValue方法,该方法将修改引用单元格的内容。因为调用方法没有指向修改后的单元格的变量,所以它无法读取参考单元格的新值。

In this case, we are making a reference cell that holds the value copied from the success7 variable, but not assigning that new reference cell to any variable. We then pass that reference cell to the GetValue method, which modifies the content of the reference cell. Because the calling method has no variable pointing to the modified cell, it has no way of reading the new value of the reference cell.

这篇关于F#等同于C#的“输出”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆