F# 相当于 C# 的“out" [英] The F# equivalent of C#'s 'out'

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

问题描述

我正在将 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);

F# 中 out 关键字的等价物是什么?

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# 交互中,结果是

In F# interactive, the result is

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# 中那样使用 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# 的“out"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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