F# 通过引用传递

问题描述 投票:0回答:4

我正在尝试在 F# 中通过引用传递。在C#中,使用ref和out关键字非常容易,但在F#中似乎没那么简单。我刚刚读过这个:http://davefancher.com/2014/03/24/passing-arguments-by-reference-in-f/,建议使用参考单元格。 (我想这意味着 C# 中没有类似的 out 关键字,您不必初始化变量来传递它。)

但无论如何,我想知道这是否是 F# 中通过引用传递的最佳/唯一方法,以及这在函数式语言中是否是一个好主意。

编辑:

我很感兴趣,因为我刚刚意识到异常正在减慢我的代码速度。我正在发起一场消灭他们的十字军东征。基本上,我的计划是这样的:假设一个函数返回一个双精度值,或者如果出现错误则抛出异常。相反,我将通过引用传递一个 double 和一个 ErrorCode 类型作为位掩码,然后向下传递值和错误。我猜我只需要让所有这些变量都是可变的。

f# functional-programming pass-by-reference out ref
4个回答
4
投票

您的问题有很多部分,我会尽力回答:

  • 建议使用参考单元

    • 是的,参考单元格(或引用单元格)是将可变数据传递到函数中的惯用方法
  • 我想这意味着 C# 中没有类似的 out 关键字,您不必初始化变量来传递它。

    • C# 通常使用
      out
      参数来表示附加返回值。在 F# 中执行此操作的惯用方法是使用元组。例如,C# 函数
      int TryParse(string s, out bool succeeded)
      就是简单的
      TryParse(s : string) -> (int, bool)
  • 如果这对于函数式语言来说是个好主意的话。

    • 这当然不是我认为的正常、惯用的 F# 代码。我表示这一点的方式是用一个受歧视的联盟来表示可能的结果:

type MyFunctionResult = 
    | Success of double
    | ErrorCase1
    | ErrorCase2 of AddditionalDataType

等等

如果您有许多使用此样式的函数,则非常容易将它们与

bind
函数组合在一起


3
投票

您可以使用

&
代替 C# 的
ref
,但以
&
为前缀的变量必须是可变的。一篇不错的文章,甚至涵盖了 PInvoke 陷阱:https://paul.blasuc.ci/posts/managing-pointers-or-pinvoke-gotcha.html.

  open System.Collections.Generic
  let dic = new Dictionary<string, string>()
  dic.Add("key", "myvalue")
  let mutable v = "" // v is mutable
  let success = dic.TryGetValue("key", &v);
  System.Console.WriteLine(v)
  let succ, value = dic.TryGetValue("key") // this is what Mark Seemann says is the comment, a shortcut for C#'s `Try...(.., out ...)` is using tuples in F#

1
投票

让我描述一下 OCaml 的作用,因为我不知道 F#,并且有人可以确认 F# 足够相似以至于我的答案适用。

在 OCaml 或 F# 等函数式编程语言中,数据默认是“不可变”的。也就是说,您需要在事物可变之前将其声明为可变的,事实上可变数据结构不如不可变数据结构常见(但并不罕见)。 现在,因为默认情况下数据是不可变的,所以如何传递参数并不重要,因为它们无论如何都不会改变。在这种情况下,传递简单的数据类型是有意义的,这些数据类型按值放入寄存器,而其他所有内容则按引用传递。

当然,可变数据类型是通过引用传递的,否则拥有它们就没有什么价值。

也许您可以给我们举一个您正在尝试做的事情的例子。您传递的是可变数据还是不可变数据?


0
投票
obj ref

并且刚刚通过

obj

browser.Navigate2(url_obj)

所以我刚刚添加了
ref

并且它起作用了


browser.Navigate2(ref url_obj)

所以我想你只需添加
ref


在使用 COM 对象时非常有用。

© www.soinside.com 2019 - 2024. All rights reserved.