.net - 理解byref、ref和&

标签 .net f# reference parameter-passing byref

嗯,我开始明白 F# 能够管理引用(某种类似于 C++ 的引用)。这使更改函数中传递的参数值成为可能,并使程序员能够返回多个值。
但是,这是我需要知道的:

  • Ref 关键字:关键字 ref用于从值创建对推断类型的该值的引用。所以
    let myref = ref 10
    

    这意味着 F# 将创建一个类型为 Ref<int> 的对象。放在那里(在可变字段中)我的 int 10 .

    好的。所以我假设 ref用于创建 Ref<'a> 的实例类型。这是正确的吗?
  • 访问值:为了访问存储在引用中的值,我可以这样做:
    let myref = ref 10
    let myval = myref.Value
    let myval2 = !myref
    

    :=运算符只是让我像这样编辑值:
    let myref = ref 10
    myref.Value <- 30
    myref := 40
    

    所以! (Bang) 取消引用我的引用。和 :=编辑它。我想这也是正确的。
  • & 运算符:这个运算符有什么作用?它是否适用于引用类型?不,我想它必须应用于可变值,这会返回什么?引用资料?地址?如果使用交互式:
    let mutable mutvar = 10;;
    &a;;
    

    最后一行抛出了一个错误,所以我不明白 & 是什么意思运营商是为了。
  • ByRef: 怎么样 byref ?这对我来说非常重要,但我意识到我不理解它。
    我知道它用于有关参数传递的功能。当他希望可以编辑传递的值时使用 byref (这有点违反函数式语言的哲学,但 f# 不止于此)。考虑以下:
    let myfunc (x: int byref) =
        x <- x + 10
    

    这很奇怪。我知道如果你有引用let myref = ref 10然后执行此操作以编辑值:myref <- 10它出现错误,因为它应该是这样的:myref := 10 .然而,事实上我可以在该函数中编辑 x使用 <-运算符意味着 x不是引用吧?

    如果我假设 x不是引用,那么我还假设,在函数中,当使用 byref 时在参数上,该参数可以应用可变语法。所以这只是一个语法问题,如果我假设我没问题,事实上,一切正常(没有编译器错误)。然而,什么是x ?
  • 调用函数:如何使用利用 byref 参数的函数?
    &运算符(operator)参与但你能解释一下吗?在本文中:MSDN Parameters and Arguments提供了以下示例:
    type Incrementor(z) =
        member this.Increment(i : int byref) =
           i <- i + z
    
    let incrementor = new Incrementor(1)
    let mutable x = 10
    // A: Not recommended: Does not actually increment the variable. (Me: why?)
    incrementor.Increment(ref x)
    // Prints 10.
    printfn "%d" x  
    
    let mutable y = 10
    incrementor.Increment(&y) (* Me: & what does it return? *)
    // Prints 11.
    printfn "%d" y 
    
    let refInt = ref 10
    incrementor.Increment(refInt) (* Why does it not work in A, but here it does? *)
    // Prints 11.
    printfn "%d" !refInt
    
  • 最佳答案

    引用关键字 是的,当你写 let a = ref 10您实际上是在写 let a = new Ref<int>(10)哪里Ref<T> type 有一个可变字段 Value .

    访问值 :=!运算符只是编写的快捷方式:

    a.Value <- 10  // same as writing: a := 10
    a.Value        // same as writing: !a
    

    ByRef 是一种特殊类型,可以(合理地)仅在方法参数中使用。这意味着参数本质上应该是指向某个内存位置(分配在堆或堆栈上)的指针。对应于outref C#中的修饰符。请注意,您不能创建这种类型的局部变量。

    & 运算符 是一种创建值(指针)的方法,该值可以作为参数传递给期望 byref 的函数/方法。类型。

    调用函数 byref 的例子之所以有效,是因为您正在向该方法传递对局部可变变量的引用。通过引用,该方法可以更改存储在该变量中的值。

    以下不起作用:
    let a = 10            // Note: You don't even need 'mutable' here
    bar.Increment(ref a)  
    

    原因是您正在创建 Ref<int> 的新实例。并且您正在复制 a 的值进入这个实例。 Increment方法然后修改存储在 Ref<int> 实例中的堆上的值,但您不再拥有对该对象的引用。
    let a = ref 10
    bar.Increment(a)  
    

    这是有效的,因为 a是类型 Ref<int> 的值并且您将指向堆分配实例的指针传递给 Increment然后使用 !a 从堆分配的引用单元格中获取值.

    (您可以使用使用 ref 创建的值作为 byref 的参数,因为编译器专门处理这种情况 - 它会自动引用 Value 字段,因为这是一个有用的场景......)。

    关于.net - 理解byref、ref和&,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5028377/

    相关文章:

    c# - 如何确定不是大写或小写的字母字符

    F# List.Map 使用随机数

    .net - 类型提供程序不适用于 .net 2.0/3.x?

    计算表达式中的 F# 递归绑定(bind)和尾递归

    javascript - 如何将参数传递给队列,然后传递给setTimeout?...困惑

    c# - 使用 ViewModel 的 Winforms 数据绑定(bind)

    c# - DotNetZip 不从 WinZip 中提取最佳压缩

    .net - 如何索引数字字段并在 Lucene.Net 中按范围搜索它们?

    c++ - 在 C++ 中使用 const 引用参数访问函数成员的最佳实践

    windows-phone-7 - 无效的 appId 必应翻译 (WP7)